LINUX.ORG.RU

Изучаю Boost::singleton

 ,


0

2

Доброго времени суток!

В общем, такая стандартная задача стоит - сделать так, чтобы создавалось не больше 1 экземпляра некоторого класса (хоть на этапе выполнения, хоть на этапе компиляции). Первое, что приходит в голову - шаблон singleton, но я че-то хз, как им пользоваться и почему оно работает (отследить момент создания нового экземпляра несложно, а вот как запретить это?)...

Пробовал вот так (не копая глубоко в исходники буста):

#include <boost/serialization/singleton.hpp>
#include <iostream>
using namespace std;
using namespace boost::serialization;

template <class T> class TServer :
    public singleton<TServer<T>>
{
private:
    int a;
    T b;
public:
    TServer(int s) : a(s){
        cout<<"TServer"<<endl;
    }
    int geta(){return a;};
    int getb(){return b;};
    void setb(const T & c){b=c;};
};

int main(int argc, char**argv)
{
    TServer<int> fg(15);
    fg.setb(-5);
    cout<<fg.geta()<<endl;
    TServer<int> fg2(25);
    cout<<fg.getb()<<endl;
    cout<<fg2.getb()<<endl;
    cout<<fg.geta()<<endl;
    cout<<fg2.geta()<<endl;
    TServer<int> *fg3=new TServer<int>(105);
    cout<<fg.geta()<<endl;
    cout<<fg2.geta()<<endl;
    cout<<fg3->geta()<<endl;
    return 0;
}

Вывод:

TServer
15
TServer
-5
0
15
25
TServer
15
25
105

То есть создаются три разных экземпляра класса.

★★

Ответ на: комментарий от anonymous

Зачем ты врешь? Есть более быстрые и безопасные окамлы и русты.
более быстрые

Зачем ты врешь? (c)

anonymous
()

А зачем тебе собственно запрещать на этапе компиляции? В плюсах ты можешь сделать так, что бы конструктор возвращал указатель на существующий экземпляр вместо создания нового, если таковой есть.

Aswed ★★★★★
()
Ответ на: комментарий от anonymous

Есть более быстрые и безопасные окамлы и русты.

более безопасные окамлы и русты

да

более быстрые окамлы и русты

нет

Aswed ★★★★★
()
Ответ на: комментарий от asaw

Я тебе уже всё написал. Если ты не понял - перечитай. И по ссылке сходи наконец.

Вы сказали, что приведенный мной пример не является классическим синглтоном. Я опроверг ваше утверждение приведя ссылки на классический синглтон.
Мне непонятно, почему вы продолжаете пердеть в лужу и выкручиваться.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Я опроверг ваше утверждение приведя ссылки на классический синглтон.

Ты привел ссылки на реализацию синглетона на джаве и на обезьянью копию этого кода на C++. Это классический пример НЕправильной реализации синглетона на С++.

Мне непонятно, почему вы продолжаете пердеть в лужу и выкручиваться.

Ты настолько глуп, что даже не можешь понять где ты не прав.

asaw ★★★★★
()
Ответ на: комментарий от Gorthauer

Полагаю товарищ имел ввиду функцию-конструткор она же фабрика, она же get_instance какая-нибудь.

anonymous
()
Ответ на: комментарий от Aswed

Конструктор по определению не возвращает значения.

Из обсуждения стало понятно, что этот паттерн - какой-то антипаттерн.

aido ★★
() автор топика
Ответ на: комментарий от aido

тебе это в первых ответах сказали. Не трогай его даже 6 метровой палкой.

anonymous
()
Ответ на: комментарий от asaw

Ты привел ссылки на реализацию синглетона на джаве и на обезьянью копию этого кода на C++. Это классический пример НЕправильной реализации синглетона на С++.

Вам кто-то сказал, что вы великий гуру? :)

Ты настолько глуп, что даже не можешь понять где ты не прав.

Полагаю, что эту фразу вы слышите очень часто в свой адрес :)

andreyu ★★★★★
()
Ответ на: комментарий от aido

Я имел ввиду перегрузку оператора «new». Его, насколько я помню, переопределить можно.

Aswed ★★★★★
()
Ответ на: комментарий от Aswed

через магию new

Так это не конструктор, конструктор вызывается и для объектов созданных на стеке.

anonymous
()
Ответ на: комментарий от anonymous

Хмм, и правда. Не подумал об этом. Тогда не знаю как это сделать.

Aswed ★★★★★
()
Ответ на: комментарий от anonymous

Ну его можно, вроде бы, и запретить, если сделать деструктор приватным.

Gorthauer ★★★★★
()
Ответ на: комментарий от asaw

Сходи уже по ссылке, которую я тебе дал, петрушка.

Клоуном тут выступаете вы.

1. Чем реализация синглтона по вашей ссылке отличается от приведенного мною примера?

2. Мой пример синглтона отвечал на вопрос ТСа.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

1. Чем реализация синглтона по вашей ссылке отличается от приведенного мною примера?

Вот этим:

Правильный синглетон. The classic lazy evaluated and correctly destroyed singleton:

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                                  // Instantiated on first use.
            return instance;
        }
    private:
        S() {};                   // Constructor? (the {} brackets) are needed here.

        // C++ 03
        // ========
        // Dont forget to declare these two. You want to make sure they
        // are unacceptable otherwise you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement

        // C++ 11
        // =======
        // We can use the better technique of deleting the methods
        // we don't want.
        S(S const&)               = delete;
        void operator=(S const&)  = delete;

};

Твой синглетон: Изучаю Boost::singleton (комментарий)

Разница очевидна любому, кто хоть что-то понимает в С++.

Клоуном тут выступаете вы.

asaw ★★★★★
()
Ответ на: комментарий от asaw

Разница очевидна любому, кто хоть что-то понимает в С++.

Ну так расскажите мне о разнице в реализации.

p.s. Пункт номер два вы успешно не заметили.

andreyu ★★★★★
()
Ответ на: комментарий от asaw

Заодно попробуйте осознать, что представляет static в данном случае и чем он отличается от if(!isInitialized) { initializeIt(); }

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Заодно попробуйте осознать, что представляет static в данном случае и чем он отличается от if(!isInitialized) { initializeIt(); }

Тем что для статика на уровне стандарта гарантируется атомарность инициализации?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Тем что для статика на уровне стандарта гарантируется атомарность инициализации?

Атомарность инициализации статика на уровне стандарта? Можно мне выдержку этого пункта?

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Атомарность инициализации статика на уровне стандарта?

Уточню, под атомарностью подразумевал не atomic, а отсутствие гонок. И да, это новшество 11 стандарта.

Можно мне выдержку этого пункта?

6.7.4

...If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

91) The implementation must not introduce any deadlock around execution of the initializer.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

Благодарю. Вот, что генерится для кода

class A
{
  int v;
public:
  A(int _v) : v(_v) {}
  int get() const { return v; }
};

int foo(int num)
{
  static A* a = new A(num);
  return a->get();
}
// gcc-4.9.2 -O2 -std=c++11

foo(int):
	cmpb	$0, guard variable for foo(int)::a(%rip)
	je	.L2
	movq	foo(int)::a(%rip), %rax
	movl	(%rax), %eax
	ret
.L2:
	pushq	%rbp
	pushq	%rbx
	movl	%edi, %ebp
	movl	guard variable for foo(int)::a, %edi
	subq	$8, %rsp
	call	__cxa_guard_acquire
	testl	%eax, %eax
	jne	.L4
	movq	foo(int)::a(%rip), %rax
	movl	(%rax), %eax
	addq	$8, %rsp
	popq	%rbx
	popq	%rbp
	ret
.L4:
	movl	$4, %edi
	call	operator new(unsigned long)
	movq	%rax, %rbx
	movl	%ebp, (%rax)
	movl	guard variable for foo(int)::a, %edi
	movq	%rax, foo(int)::a(%rip)
	call	__cxa_guard_release
	movq	%rbx, %rax
	movl	(%rax), %eax
	addq	$8, %rsp
	popq	%rbx
	popq	%rbp
	ret
	movq	%rax, %rbx
	movl	guard variable for foo(int)::a, %edi
	call	__cxa_guard_abort
	movq	%rbx, %rdi
	call	_Unwind_Resume
andreyu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.