c++ - 单例:为什么不需要删除并且看不到析构函数调试消息
问题描述
我的导师说我们不需要删除在堆中创建的单例对象,因为当超出范围时,它的内存会被释放并自动删除。
是不是编译器对静态对象的处理方式不同,我们不需要担心从堆中删除这个对象?
在下面的代码中,我认为是指针超出了 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;
}
期望对象析构函数在屏幕上显示一条消息,因为它被调用了。
解决方案
那是因为你有一个错误。这里
Singleton* Singleton::GetInstance() {
if (psingleton = NULL) {
psingleton = new Singleton();
}
return psingleton;
}
永远不会制作对象,因为psingleton = NULL
总是被强制转换为false
. 你想要的是if (psingleton == NULL) {
.
有了这个修复,我在 MSVC 中的输出是:
单个对象
在析构函数
...这是因为调用Singleton::GetInstance()->DeleteObject();
,而不是因为程序已经结束。
我认为这是超出范围的指针,而不是堆本身中的对象,但是在某些时候,如果确实为该对象释放了内存,则应该调用对象的析构函数?
你是对的。堆上的对象不会超出范围,并且不会仅从程序结束调用析构函数。
推荐阅读
- javascript - Node.js 事件循环问题
- python - 拆分和连接熊猫中多行的字符串
- python - 如何使用 pytest-qt 鼠标单击在 QTableWidget 中选择一个项目?
- bash - 在 UNIX 中使用通配符比较两个数组
- javascript - 如何按照从 Firebase 检索/插入的顺序将数组的数据附加到 DOM 元素?
- javascript - 没有使用 java 脚本更改 HTML 输入字段的属性
- javascript - 如何使用 lodash 中的 _.union 对打字稿中的多个数组进行重复数据删除?
- excel - Excel VBA:运行宏而不选择单元格
- cron - 从 puppet 的 cronjob 资源中,我只想将 cron 作业错误日志附加到不同的路径
- python - 在 CNN 中使用全局总和池化而不是全局平均池化