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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
#1

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

25.02.2014, 05:29. Просмотров 616. Ответов 14
Метки нет (Все метки)

Доброе утро!

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

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();
 
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.02.2014, 05:29
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Мой синглтон. Дайте рекомендации, оцените, пожалуйста (C++):

Функция replace(). Дайте рекомендации, пожалуйста - C++
Добрый вечер! Написал не сложную функцию replace, но чувствую, что с утечками памяти тут не всё хорошо. Не могли бы дать рекомендации,...

Оцените мой Doodle Jump - C++
Написал клон всем известной игры Doodle Jump. Прошу оценить и дать советы. Реализованы основные функции. Пока нету поворота игрока( смотрит...

Оцените мой первый урок по С++ - C++
Тут вот недавно приспичило урок по С++ написать. Сделано, а вот понять что за зверек получился надо (я про вас). Стоит ли продолжать или я...

Отсортировать struct. (дайте тест, который "сломает" мой код) - C++
Выведите фамилии и имена учащихся в порядке убывания их среднего балла. Входные данные Заданы сначала количество учащихся n, затем n...

Дайте, пожалуйста, контрпримеры - C++
Задача №93 в acmp задание в тему

Дайте алгоритм, пожалуйста =)) - C++
Связной граф задан матрицей смежности. Написать программу для поиска всех циклов графа. Я уже сам задал матрицу смежности, а что дольше...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
25.02.2014, 09:12 #2
Он же у тебя шаблонный. Делай всю реализацию в заголовочном файле.
0
Tulosba
:)
Эксперт С++
4396 / 3239 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
25.02.2014, 11:24 #3
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Tsingleton
OMG
Цитата Сообщение от Юрий Ч Посмотреть сообщение
std::auto_ptr
Устаревший класс. Не рекомендован к использованию.
0
Юрий Ч
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;
};
0
Tulosba
:)
Эксперт С++
4396 / 3239 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
25.02.2014, 11:53 #5
Цитата Сообщение от Юрий Ч Посмотреть сообщение
C++
1
2
template<typename U>
 friend struct An;
Это значит An<U> будет другом An<T>
Цитата Сообщение от Юрий Ч Посмотреть сообщение
!!! Не совсем понятно для чего тип U?
Для преобразования из An<U> в An<T>
1
Юрий Ч
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)) {}
0
Tulosba
:)
Эксперт С++
4396 / 3239 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
25.02.2014, 12:16 #7
Цитата Сообщение от Юрий Ч Посмотреть сообщение
но data, это шаблон умного указателя типа T.
Указатель на базовый класс может хранить указатель на производный.

Добавлено через 55 секунд
Цитата Сообщение от Юрий Ч Посмотреть сообщение
из-за двойной ссылки &&
это не двойная ссылка это rvalue-reference. (С++11)
0
Юрий Ч
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)) {}
0
Tulosba
:)
Эксперт С++
4396 / 3239 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
25.02.2014, 12:26 #9
Цитата Сообщение от Юрий Ч Посмотреть сообщение
под C++10?
С++10 не существует
Под С++03 просто убрать данный конструктор.
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
25.02.2014, 13:13 #10
Я не понимаю, как синглтон может быть шаблонным?
Типичный синглтон ценен тем, что его конструктор приватный, не позволяющий при всём желании создать лишний экземпляр класса. Но тут создать лишний экземпляр проще пареной репы: достаточно написать вместо
C++
1
2
MyClass* ptr=Tsingleton<MyClass>::getInstance();
MyClass* ptr=new MyClass;
разве не? И синглтон сломается!
0
Юрий Ч
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; }
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
25.02.2014, 13:33 #12
Юрий Ч, так вторая ж шаблонная! Если не указывать шаблонность при вызове, она и не вызовется!
0
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
25.02.2014, 13:44  [ТС] #13
Но тут то вызывается без уточнения типа:

C++
1
void reinit()                     { anFill(*this); // - anFill шаблонная. }
0
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
25.02.2014, 16:06 #14
Юрий Ч, мог бы и выложить, что такое anFill ! Пришлось гуглить, с какого сайта ты это достал, лезть в статью...
Так ведь anFill - специализированный шаблон! Вот и ответ.
1
Юрий Ч
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/, но что-то нет того функционала (см. //!!!), что описан в статье. Может я что-то не так делаю?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2014, 12:05
Привет! Вот еще темы с ответами:

Дайте пожалуйста ответы - C++
1) Почему при объявлении матрицы с одновременной инициализацией первые скобки можно оставить пустыми, а вторые нет? 2) Как вывести...

Дайте пожалуйста задачку - C++
Помогите вот с чем, изучаю C++ для себя, в среднем понимание есть, но практики нету, хотелось бы что нибудь написать интересно, но не знаю...

Дайте , пожалуйста, подсказки по коду - C++
Добрый день! Подскажите, пожалуйста, по коду ниже. Это несложный код из книги Р. Лафоре. #include &lt;iostream&gt; using namespace std; ...

Дайте пожалуйста ссылку на сайт с командами - C++
Помогите вспомнить на сайт с командами и функциями для С++, точно не помню на кажется эта страница была на сайте Microsoft, но что то не...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.02.2014, 12:05
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru