2016-12-05 2 views
3

В нормальном одноплодном шаблоне, одноэлементный класс эффективен «запечатанный» (не может быть получен):Singleton шаблон для выводимого класса

class A 
{ 
private: 
    static A m_instance; // instance of this class, not a subclass 

    // private ctor/dtor, so class can't be derived 
    A(); 
    ~A(); 

public: 
    static A& GetInstance() { return m_instance; } 

    ... 
}; 

Как бы вы написать класс, который предназначен быть получен, но чье производный класс должен быть создан только один раз?

+0

Связанные: HTTP: // StackOverflow. com/questions/5739678/c-templates-and-the-singleton-pattern –

ответ

4

Как вы напишете класс, который должен быть выведен, но чей производный класс должен быть создан только один раз?

Вы можете использовать CRTP, чтобы понять, что:

template<typename Derived> 
class A 
{ 
protected: // Allow to call the constructor and destructor from a derived class 
    A(); 
    ~A(); 

public: 
    static T& GetInstance() { 
     static T theInstance; // Better way than using a static member variable 
     return theInstance; 
    } 

    ... 
}; 

и использовать это нравится

class B : public A<B> { 
    // Specific stuff for derived class 
}; 

Обратите внимание, что этот способ имеет наибольший смысл, если базовый класс предоставляет некоторые общая реализация (кроме функции GetInstance()) реализована на основе интерфейса, предоставляемого производным классом.

Всякий раз, когда вызов производного класса в базовом классе необходимо вы можете безопасно использовать static_cast<Derived*>(this) для доступа к нему (не virtual или чисто virtual функции не нужны):

template<typename Derived> 
void A<Derived>::doSomething { 
     // Execute the functions from Derived that actually implement the 
     // warranted behavior. 
     static_cast<Derived*>(this)->foo(); 
     static_cast<Derived*>(this)->bar(); 
} 
+0

Является ли 'static T theInstance;' объективно 'лучше'? Неужели и скомпилировать то же самое? – Michael

+1

@ Майкл, он не будет скомпилировать то же самое, и именно поэтому это лучше. –

+2

@Michael Посмотрите на Singleton_Scott Meyer's и почему это продвинутый и лучший способ (например, безопасность потока). –

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