2011-12-23 2 views
1

Можно создать дубликат:
A Singleton that is not globally accessibleне глобальный шаблон дизайна Singleton?

Вы знаете, хороший шаблон дизайна, который будет убедиться, что только один экземпляр объекта создается без этого объекта глобального в C++? Это то, что делает один синглтон, но мне действительно нужно, чтобы он не был глобальным для обеспечения безопасности доступа к коду.

Спасибо за помощь!

+2

Типичный синглтон шаблон инкапсулирует объект singleton как частный статический член одноэлементного класса и предоставляет метод 'Instance()' для доступа. Этого недостаточно? –

+0

Это то, что вы хотите, чтобы только некоторые классы могли получать объект singleton? – davogotland

+0

Нет, мне не разрешено использовать Singleton, потому что с этим шаблоном экземпляр объекта является глобальным, а затем доступен везде в программе, которая небезопасна. – koleror

ответ

2

локального класса Я думаю, что вы что-то вроде этого (примечание: скопировано с an answer I already wrote and forgot about):

#include <stdexcept> 

// inherit from this class (privately) to ensure only 
// a single instance of the derived class is created 
template <typename D> // CRTP (to give each instantiation its own flag) 
class single_instance 
{ 
protected: // protected constructors to ensure this is used as a mixin 
    single_instance() 
    { 
     if (mConstructed) 
      throw std::runtime_error("already created"); 

     mConstructed = true; 
    } 

    ~single_instance() 
    { 
     mConstructed = false; 
    } 

private: 
    // private and not defined in order to 
    // force the derived class be noncopyable 
    single_instance(const single_instance&); 
    single_instance& operator=(const single_instance&); 

    static bool mConstructed; 
}; 

template <typename T> 
bool single_instance<T>::mConstructed = false; 

Теперь вы получите исключение, если класс строится больше, чем когда-то:

class my_class : private single_instance<my_class> 
{ 
public: 
    // usual interface (nonycopyable) 
}; 

int main() 
{ 
    my_class a; // okay 
    my_class b; // exception 
} 

Там нет никакого способа, чтобы реализовать политику одного экземпляра во время компиляции в C++, хотя.


(Также хорошо на вас для заметив, что одноэлементные тупые. Глобально доступны и однократно creatable два разных понятия, и должны быть объединены только по совпадению, а не дизайн.)

1

Вы можете использовать одноэлементный режим с обычной статической функцией доступа Instance(), но выполните эту функцию private. Доступ затем предоставляется только другому классу, делая его friend classes класса singleton.

+1

Это не отличается от глобального с дополнительным уровнем косвенности (какая ошибка вы получаете, когда класс друга создается в двух разных местах? Нет? Тогда вопрос не выполнен.) – GManNickG

+0

Я думаю, что Johannes Gerer прав, только члены друга могут получить доступ к 'instance()', поэтому доступ к сервисам, предоставляемым singleton и его данными, зарезервирован для функций класса друга. я задаюсь вопросом, может ли положить синглтон внутри другого класса также решить проблему –

+0

@eharvest: Когда-то это синглтон, это глобально навсегда. Это не так (за исключением неправильной реализации одного синглтона). И если вы попытаетесь создать код вокруг него, зачем начинать с сингла? – GManNickG

0

Сделать конструктор (ы) и назначать оператора private.

Затем создайте единственную функцию, которая создаст один экземпляр вашего класса другом класса.
Поскольку вы пишете функцию, это единственный, который может создать объект (и других приложений в приложении не будет).

+0

Я знаю, что могу легко управлять созданием объекта, но проблема в том, что после создания, поскольку объект является глобальным, он доступен из всей программы. Я ошибаюсь? Если да, можете ли вы дать мне какой-нибудь псевдокод, который покажет мне, как это сделать? Спасибо! – koleror

+0

единственный экземпляр не является глобальным, если только метод экземпляра класса singleton не является или ссылкой на него. созданный синглтон доступен только по коду, который имеет ссылку на него или ему разрешено получить ссылку на него. ссылка на singleton может быть конфиденциальной, и метод, описанный Johannes и Loki, может гарантировать, что вы контролируете, какой код имеет доступ к методу class/instance; поэтому дает вам полный контроль. –

Смежные вопросы