Форум программистов, компьютерный форум CyberForum.ru

Мой синглтон. Дайте рекомендации, оцените, пожалуйста - C++

Восстановить пароль Регистрация
 
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 05:29     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #1
Доброе утро!

Вот, наваял тут типа синглтон. Можете дать замечания по данной реализации. Спасибо!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Z:\programming\classes_cpp\general\gen_Tsingleton_pat\gen_Tsingleton_pat.h
 
#ifndef __GEN_TSINGLETON_PAT_H_
#define __GEN_TSINGLETON_PAT_H_
 
 
#include <memory>
 
 
/**
*
*/
template <class X> class gen_Tsingleton_pat
{
 
    public:     
 
        static X* instance();
 
    protected:
 
        static std::auto_ptr<X> m_obj_;
 
        gen_Tsingleton_pat();
        virtual ~gen_Tsingleton_pat();
 
    private:
 
        gen_Tsingleton_pat(const gen_Tsingleton_pat& obj);
        gen_Tsingleton_pat& operator=(const gen_Tsingleton_pat& obj);
 
};
 
 
#endif // __GEN_TSINGLETON_PAT_H_
 
 
// Z:\programming\classes_cpp\general\gen_Tsingleton_pat\gen_Tsingleton_pat.cpp
 
 
#include "Z:\programming\classes_cpp\general\gen_Tsingleton_pat\gen_Tsingleton_pat.h"
 
 
/**
*
*/
template <class X> gen_Tsingleton_pat<X>::gen_Tsingleton_pat()
{
}
 
 
/**
*
*/
template <class X> gen_Tsingleton_pat<X>::~gen_Tsingleton_pat()
{
}
 
 
/**
*
*/
template <class X> X* gen_Tsingleton_pat<X>::instance()
{
 
    if(!m_obj_)
        m_obj_ = std::auto_ptr<X>(new X);
    return m_obj_.get();
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.02.2014, 05:29     Мой синглтон. Дайте рекомендации, оцените, пожалуйста
Посмотрите здесь:

Дайте алгоритм, пожалуйста =)) C++
C++ Дайте пожалуйста ответы
C++ Дайте пожалуйста ссылку на сайт с командами
C++ Дайте, пожалуйста, контрпримеры
C++ Дайте,пожалуйста, совет по поводу задания
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
25.02.2014, 09:12     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #2
Он же у тебя шаблонный. Делай всю реализацию в заголовочном файле.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2014, 11:24     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #3
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Tsingleton
OMG
Цитата Сообщение от Юрий Ч Посмотреть сообщение
std::auto_ptr
Устаревший класс. Не рекомендован к использованию.
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 11:49  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #4
На абракадабре приводят другую реализацию синглтона с крутыми макросами и инверсией зависимости. Всё бы хорошо, вот только макросы останавливают и есть недопонимание кода. Статья тут - http://habrahabr.ru/post/118368/, а недопонимание кода тут возникло:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
template<typename T>
struct An
{
    template<typename U>
    friend struct An;                     //!!! Что за член такой? Может, это декларация типа?
 
    An()                              {}
 
    template<typename U>           //!!! Не совсем понятно для чего тип U?
    An(const An<U>& a) : data(a.data) {}
 
    template<typename U>
    An(An<U>&& a) : data(std::move(a.data)) {}
 
    T* operator->()                   { return get0(); }
    const T* operator->() const       { return get0(); }
    bool isEmpty() const              { return !data; }
    void clear()                      { data.reset(); }
    void init()                       { if (!data) reinit(); }
    void reinit()                     { anFill(*this); }
    
    T& create()                       { return create<T>(); }
 
    template<typename U>
    U& create()                       { U* u = new U; data.reset(u); return *u; }
    
    template<typename U>
    void produce(U&& u)               { anProduce(*this, u); }
 
    template<typename U>
    void copy(const An<U>& a)         { data.reset(new U(*a.data)); }
 
private:
    T* get0() const
    {
        const_cast<An*>(this)->init();
        return data.get();
    }
 
    std::shared_ptr<T> data;
};
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2014, 11:53     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #5
Цитата Сообщение от Юрий Ч Посмотреть сообщение
C++
1
2
template<typename U>
 friend struct An;
Это значит An<U> будет другом An<T>
Цитата Сообщение от Юрий Ч Посмотреть сообщение
!!! Не совсем понятно для чего тип U?
Для преобразования из An<U> в An<T>
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 12:15  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #6
Вот тут параметризованный конструктор:

C++
1
2
    template<typename U>
    An(const An<U>& a) : data(a.data) {}
Передают константную ссылку на объект типа An<U>, но data, это шаблон умного указателя типа T. Тут как-то не совсем понятно.

Добавлено через 2 минуты
И здесь как-то не совсем понятно из-за двойной ссылки &&:

C++
1
2
    template<typename U>
    An(An<U>&& a) : data(std::move(a.data)) {}
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2014, 12:16     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #7
Цитата Сообщение от Юрий Ч Посмотреть сообщение
но data, это шаблон умного указателя типа T.
Указатель на базовый класс может хранить указатель на производный.

Добавлено через 55 секунд
Цитата Сообщение от Юрий Ч Посмотреть сообщение
из-за двойной ссылки &&
это не двойная ссылка это rvalue-reference. (С++11)
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 12:23  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #8
А можно как-то адаптировать данный код под C++10?

C++
1
2
template<typename U>
    An(An<U>&& a) : data(std::move(a.data)) {}
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2014, 12:26     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #9
Цитата Сообщение от Юрий Ч Посмотреть сообщение
под C++10?
С++10 не существует
Под С++03 просто убрать данный конструктор.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
25.02.2014, 13:13     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #10
Я не понимаю, как синглтон может быть шаблонным?
Типичный синглтон ценен тем, что его конструктор приватный, не позволяющий при всём желании создать лишний экземпляр класса. Но тут создать лишний экземпляр проще пареной репы: достаточно написать вместо
C++
1
2
MyClass* ptr=Tsingleton<MyClass>::getInstance();
MyClass* ptr=new MyClass;
разве не? И синглтон сломается!
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 13:25  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #11
Ещё вопросы.

C++
1
2
3
4
5
6
7
8
    void reinit() { anFill(*this); } //!!! anFill - это параметризованная функция, определяет тип по типу параметра?
 
    // А тут как быть? две функции почти одинаковы, не будет неоднозначности при вызове?
 
    T& create()                       { return create<T>(); }
 
    template<typename U>
    U& create()                       { U* u = new U; data.reset(u); return *u; }
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
25.02.2014, 13:33     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #12
Юрий Ч, так вторая ж шаблонная! Если не указывать шаблонность при вызове, она и не вызовется!
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 13:44  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #13
Но тут то вызывается без уточнения типа:

C++
1
void reinit()                     { anFill(*this); // - anFill шаблонная. }
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
25.02.2014, 16:06     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #14
Юрий Ч, мог бы и выложить, что такое anFill ! Пришлось гуглить, с какого сайта ты это достал, лезть в статью...
Так ведь anFill - специализированный шаблон! Вот и ответ.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2014, 12:05     Мой синглтон. Дайте рекомендации, оцените, пожалуйста
Еще ссылки по теме:

Оцените мой Doodle Jump C++
Оцените мой первый урок по С++ C++
C++ Отсортировать struct. (дайте тест, который "сломает" мой код)

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
26.02.2014, 12:05  [ТС]     Мой синглтон. Дайте рекомендации, оцените, пожалуйста #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Файл "Z:\programming\classes_cpp\general\gen_Tsi_pat\gen_Tsi_pat.h"
 
#ifndef __GEN_TSI_PAT_H_
#define __GEN_TSI_PAT_H_
 
#define PROTO_IFACE(D_iface, D_an)    \
    template<> void anFill<D_iface>(An<D_iface>& D_an)
 
#define DECLARE_IMPL(D_iface)    \
    PROTO_IFACE(D_iface, a);
 
#define BIND_TO_IMPL(D_iface, D_impl)    \
    PROTO_IFACE(D_iface, a) { a.create<D_impl>(); }
 
#define BIND_TO_SELF(D_impl)    \
    BIND_TO_IMPL(D_impl, D_impl)
 
#define BIND_TO_IMPL_SINGLE(D_iface, D_impl)    \
    PROTO_IFACE(D_iface, a) { a = anSingle<D_impl>(); }
 
#define BIND_TO_SELF_SINGLE(D_impl)    \
    BIND_TO_IMPL_SINGLE(D_impl, D_impl)
 
#define BIND_TO_IFACE(D_iface, D_ifaceFrom)    \
    PROTO_IFACE(D_iface, a) { anFill<D_ifaceFrom>(a); }
 
#define BIND_TO_PROTOTYPE(D_iface, D_prototype)    \
    PROTO_IFACE(D_iface, a) { a.copy(anSingle<D_prototype>()); }
 
#include <memory>
#include <string>
 
 
 
template<typename T>
struct An
{
    template<typename U>
    friend struct An;
 
    An()                              {}
 
    template<typename U>
    An(const An<U>& a) : data(a.data) {}
 
    template<typename U>
    An(An<U>&& a) : data(std::move(a.data)) {}
 
    T* operator->()                   { return get0(); }
    const T* operator->() const       { return get0(); }
    bool isEmpty() const              { return !data; }
    void clear()                      { data.reset(); }
    void init()                       { if (!data) reinit(); }
    void reinit()                     { anFill(*this); }
    
    T& create()                       { return create<T>(); }
 
    template<typename U>
    U& create()                       { U* u = new U; data.reset(u); return *u; }
    
    template<typename U>
    void produce(U&& u)               { anProduce(*this, u); }
 
    template<typename U>
    void copy(const An<U>& a)         { data.reset(new U(*a.data)); }
 
private:
    T* get0() const
    {
        const_cast<An*>(this)->init();
        return data.get();
    }
 
    std::shared_ptr<T> data;
};
 
 
template<typename T>
struct AnAutoCreate : An<T>
{
    AnAutoCreate()     { create(); }
};
 
template<typename T>
T& single()
{
    static T t;
    return t;
}
 
template<typename T>
An<T> anSingle()
{
    return single<AnAutoCreate<T>>();
}
 
 
template<typename T>
void anFill(An<T>& a)
{
    throw std::runtime_error(std::string("Cannot find implementation for interface: ")
            + typeid(T).name());
}
 
#endif // __GEN_TSI_PAT_H_
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// h
 
#include "Z:\programming\classes_cpp\general\gen_Tsi_pat\gen_Tsi_pat.h"
 
 
struct X
{
    X()            { x = 1; }
    
    int x;
};
 
// декларация заливки реализации
DECLARE_IMPL(X)
 
int init();
 
// cpp
 
struct Y : X
{
    Y()            { x = 2; }
        
    int y;
};
 
// связывание декларации X и реализации Y используя синглтон
BIND_TO_IMPL_SINGLE(X, Y)
 
 
int init()
{
 
    An<X> x;    
    return x->x;             //!!! Возврящает 1, а в статье говорится, что вернул 2. 
 
}
Попробовал пример синглтона из статьи http://habrahabr.ru/post/118368/, но что-то нет того функционала (см. //!!!), что описан в статье. Может я что-то не так делаю?
Yandex
Объявления
26.02.2014, 12:05     Мой синглтон. Дайте рекомендации, оцените, пожалуйста
Ответ Создать тему
Опции темы

Текущее время: 03:52. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru