2017-08-04 99 views
3

這是一種合法的方式來創建一個基礎單體對象,以確保它的所有子對象都是單例對象嗎?我想將這與工廠模式結合使用,以確保所有因子都是單身。C++中的基礎單體對象

關鍵類是爲了防止孩子在單身構造函數週圍黑客攻擊,但基本上只是一個形式參數。

這種方法有什麼特別的錯誤嗎?

class singleton 
{ 
protected: 
    struct key 
    { 
    private: 
     friend class singleton; 

     key(){} 
    }; 

public: 
    singleton(const key&) 
    {} 

    template <class child> static child* getInstance() 
    { 
     static key instanceKey; 
     static child* unique = new child(instanceKey); 

     return unique; 
    } 

private: 
}; 

class test : public singleton 
{ 
public: 
    test(singleton::key& key) 
     : singleton(key) 
    {} 

    void init() 
    { 
     //init object 
    } 

private: 
}; 

int main() 
{ 
    test* t = singleton::getInstance<test>(); 

    return 0; 
} 

回答

0

我添加了一個類來刪除所有工廠的結尾。 :) 你需要一個虛擬析構函數的鏈。除此之外,我還沒有發現其他內存泄漏,並且這些實例是唯一的。 '鑰匙'的安全機制似乎也很好。我沒有辦法讓我的手在靜態函數之外的某個鍵上。

#include <iostream> 
#include <set> 

class Singleton; 

class Set_of_Singletons 
{ 
    friend class Singleton; 
private: 
    std::set<Singleton*> instances; 

    Set_of_Singletons():instances(){} 
public: 
    ~Set_of_Singletons(); 
}; 

class Singleton 
{ 
private: 
    static Set_of_Singletons children; 

protected: 
    struct key 
    { 
    private: 
     friend class Singleton; 

     key(){} 
    };  
public: 
    template <class Child> static Child* doNew() 
    { 
     static key instanceKey; 
     Child* u = new Child(instanceKey); 
     children.instances.insert((Singleton*)u); 
     return u; 
    } 

    template <class Child> static Child* getInstance() 
    { 
     static Child* unique = doNew<Child>(); 
     return unique; 
    } 

    Singleton(const key&) 
    {} 

    virtual ~Singleton(){} 
}; 

Set_of_Singletons::~Set_of_Singletons() 
{ 
    for (auto inst: instances) 
     delete inst; 

    instances.clear(); 
} 

Set_of_Singletons Singleton::children; 

class B: public Singleton 
{ 
public: 
    B(Singleton::key& key) 
     : Singleton(key) 
    { 
     std::cout << ">>>> Construction of B \n";  
    } 

    virtual ~B() 
    { 
     std::cout << "<<<< Destruction of B \n";  
    } 

}; 

class C final: public Singleton 
{ 
public: 
    C(Singleton::key& key) 
     : Singleton(key) 
    { 
     std::cout << ">>>> Construction of C \n"; 
    } 

    virtual ~C() 
    { 
     std::cout << "<<<< Destruction of C \n";  
    } 
}; 

int main() 
{ 
    // Object creation seems all ok 
    B* x = Singleton::getInstance<B>(); 
    std::cout << "x: " << x << "\n";  

    B* y = Singleton::getInstance<B>(); 
    std::cout << "y: " << y << "\n"; 

    C* v = Singleton::getInstance<C>(); 
    std::cout << "v: " << v << "\n"; 

    C* w = Singleton::getInstance<C>(); 
    std::cout << "w: " << w << "\n"; 
    return 0; 
} 

// ~Have fun.~ 
0

您可以使用CRTP類似:

template <typename T> 
class Singleton 
{ 
public: 
    Singleton(const Singleton&) = delete; 
    Singleton& operator=(const Singleton&) = delete; 

    static T& getInstance() { 
     static_assert(std::is_base_of<Singleton, T>::value, "T should inherit of Singleton"); 
     static T instance; 
     return instance; 
    } 
protected: 
    Singleton() = default; 
    ~Singleton() = default; 
}; 

然後

class MyFactory : Singleton<MyFactory> 
{ 
private: 
    friend class Singleton<MyFactory>; 
    MyFactory() = default; 
public: 
    //... 
};