单例类必须有私有析构函数吗?
class A{
private:
~A() {}
public:
static A &getGlobalA() {
static A a2; // <- or here - better technique
return a2; // this is initialized upon 1st access
}; // and destroyed on program exit
static A a; // <- constructor, destructor accessed from here
};
A A::a; // <- but "called" from here in terms of control flow
static
是最方便的方法之一。在a2
被销毁期间(全局销毁时)调用getGlobalA
会产生什么效果?我担心这会导致未定义行为。 - Matthieu M.这可能不是你所寻找的...但是作为参考,我使用它如下:
// .h
class Foo {
public:
static Foo* getInstance();
static void destroy();
private:
Foo();
~Foo();
static Foo* myInstance;
};
// .cpp
Foo* Foo::myInstance = NULL;
Foo* Foo::getInstance(){
if (!myInstance){
myInstance = new Foo();
}
return myInstance;
}
void Foo::destroy(){
delete myInstance;
myInstance = NULL;
}
在我的程序结尾处,我调用对象的destroy方法。正如Péter所指出的,系统会在程序结束时回收内存,因此没有真正的理由。我使用destroy的原因是当Ogre抱怨我没有释放所有分配的内存时。之后,我只是将其用作“好习惯”,因为我喜欢清理自己留下的东西。
destroy
时,也会提供一个泄漏的抽象。您应该查阅Alexandrescu的“现代C++设计”并从Loki::Singleton
中获得灵感。 - Matthieu M.在我看来,单例模式的析构函数应该是私有的。否则,某些人可能会调用“delete”来删除您的单例实例。我知道,通常没有人会这样做。但是,如果我们谈论卓越设计,它必须能够抵御所有可能的故意或无意的破坏。
使用现代C ++,甚至可以为静态构造对象声明私有析构函数。以下是我的Singleton代码片段:
class Singleton
{
public:
static Singleton& GetInstance();
// Before C++ 11
private:
Singleton() {}
~Singleton() {}
Singleton(const Singleton&); // Without implementation
Singleton& operator=(const Singleton&); // Without implementation
// Since C++ 11
private:
Singleton() = default;
~Singleton() = default;
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton& Singleton::GetInstance()
{
static Singleton instance;
return instance;
}
GetSingleton()->~CSingleton()
。 - MSaltersp = GetSingleton()
,然后注释说:「妈妈告诉我一定要删除我的指针:」delete p;
- Matthieu M.通常情况下,C++中的对象不会有私有析构函数。需要记住的是,Singleton表示只有一个实例,因此需要控制/防止的是构造而不是销毁。通常,单例具有一个私有构造函数,一个公共析构函数,一个私有静态实例变量和一个公共静态Singleton获取/懒惰构造函数,虽然该模式有一些变种。
class Factory : public IFactory
{
private:
/**
* This class should not be instantiated through its constructor. Since, it implements
* Singleton pattern.
*/
Factory();
public:
virtual ~Factory();
/**
* Accessor method for singleton instance.
* \note use this static method to access to operations of this class.
*/
static IFactory& instance(){
if(!m_instance.get()){
m_instance.reset(new Factory());
}
return static_cast<IFactory&>(*m_instance);
}
/**
* \see IFactory::create
*/
virtual boost::shared_ptr<IConnector> create();
private:
/* Singleton instance */
static boost::scoped_ptr<Factory> m_instance;
};
static_cast
是不必要的(你可以从派生类隐式转换到基类),它还算不错。但是,你应该尝试理解销毁后访问的问题。 - Matthieu M.Singleton * potatoe = &Singleton::getInstance();
// "class.hpp" file
class Singleton {
public:
static Singleton& getInstance() {
static Singleton S;
return S;
}
private:
Singleton();
~Singleton();
};
// "main.cpp" file
#include "class.hpp"
int main()
{
Singleton * patatoe = &Singleton::getInstance();
Singleton * tomatoe = &Singleton::getInstance();
Singleton * salad = &Singleton::getInstance();
return 0;
}
:)
- sbi:)
- sbi