首页 > 解决方案 > 单例:为什么不需要删除并且看不到析构函数调试消息

问题描述

我的导师说我们不需要删除在堆中创建的单例对象,因为当超出范围时,它的内存会被释放并自动删除。

是不是编译器对静态对象的处理方式不同,我们不需要担心从堆中删除这个对象?

在下面的代码中,我认为是指针超出了 main 的范围,而不是堆本身的对象,但是在某些时候,如果确实为该对象释放了内存,则应该调用对象的析构函数?

我也尝试在 main 中添加成员函数 DeleteObject,但我看不到堆中对象的析构函数被调用。

但仍然看不到析构函数在屏幕上显示消息。

#include <iostream>
using namespace std;

class Singleton {
public:
static Singleton* GetInstance();
void Show() { cout << "Single object"; }
void DeleteObject();
~Singleton();

private:
static Singleton* psingleton;
Singleton();
};

void Singleton::DeleteObject() {
delete psingleton;
}

Singleton::~Singleton() {
cout << "\n\nAt Destructor";
}

Singleton* Singleton::psingleton = 0;
Singleton::Singleton()
{
//do stuff
}

Singleton* Singleton::GetInstance() {
if (psingleton = NULL ) {
psingleton = new Singleton();
}
return psingleton;
}

int main()
{
Singleton::GetInstance()->Show();
Singleton::GetInstance()->DeleteObject();//another try
return 0;
}

期望对象析构函数在屏幕上显示一条消息,因为它被调用了。

标签: c++singletondestructor

解决方案


那是因为你有一个错误。这里

Singleton* Singleton::GetInstance() {
     if (psingleton = NULL) {
        psingleton = new Singleton();
    }
    return psingleton;
}

永远不会制作对象,因为psingleton = NULL总是被强制转换为false. 你想要的是if (psingleton == NULL) {.

有了这个修复,我在 MSVC 中的输出是:

单个对象

在析构函数

...这是因为调用Singleton::GetInstance()->DeleteObject();,而不是因为程序已经结束。


我认为这是超出范围的指针,而不是堆本身中的对象,但是在某些时候,如果确实为该对象释放了内存,则应该调用对象的析构函数?

你是对的。堆上的对象不会超出范围,并且不会仅从程序结束调用析构函数。


推荐阅读