所以我写了一个简单的单例类。当我创建一个对象时,会调用构造函数,但它的析构函数(释放对象)在超出范围时似乎不会被调用。
#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton &getInstance( )
{
if (instance == nullptr) {
cout << "Creating instance.\n";
instance = new Singleton();
}
return *instance;
}
static void destroyInstance( )
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
delete instance;
instance = nullptr;
}
}
~Singleton( )
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
delete instance;
instance = nullptr;
}
}
private:
Singleton( ) { }
static Singleton *instance;
};
Singleton *Singleton::instance = nullptr;
int main( )
{
Singleton &singleton = Singleton::getInstance();
//singleton.destroyInstance();
return 0;
}
使用析构函数代码,程序只输出它。
Creating instance.
如果我注释掉析构函数并使用destroyInstance()
函数,则输出它。
Creating instance.
Destorying instance.
为什么要这样做?
编辑:我是个白痴。只是忽略了一堆东西。这个问题也可能被删除,因为它不是那么有用。答案 0 :(得分:5)
你的析构函数中的逻辑是奇怪的递归:
~Singleton( )
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
delete instance;
instance = nullptr;
}
}
您在析构函数中调用实例上的delete,但调用delete是触发析构函数运行的原因!
你说析构函数在超出范围时不会被调用,但请记住你用new
创建了你的单例;当范围结束时,这些对象不再自动调用它们的析构函数。
除非你真的迫切需要在程序中间销毁并重新创建你的单身人士(在我的经验中极为罕见),否则只需创建这样的单身人士:
static Singleton& getInstance() {
static Singleton s;
return s;
}
摆脱destroyInstance
,让析构函数自行清理,而不必担心静态实例。
答案 1 :(得分:0)
使用智能指针(#include <memory>
)
#include <iostream>
#include <memory>
using namespace std;
class Singleton {
public:
static Singleton &getInstance()
{
if (instance == nullptr) {
cout << "Creating instance.\n";
instance = std::shared_ptr<Singleton>(new Singleton());
}
return *instance;
}
static void destroyInstance()
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
instance.reset();
instance = nullptr;
}
}
~Singleton()
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
instance.reset();
instance = nullptr;
}
}
private:
Singleton() { }
static std::shared_ptr<Singleton> instance;
};
std::shared_ptr<Singleton> Singleton::instance = nullptr;
int main()
{
Singleton &singleton = Singleton::getInstance();
//singleton.destroyInstance();
return 0;
}