辛格尔顿:为什么没有必要删除并不能看到析构函数调试消息

问题描述 投票:0回答:3

我的教练说,我们并不需要删除堆上创建一个单独的对象,因为当超出范围的内存被释放,并自动删除。

难道编译器将静态对象的不同,我们并不需要担心从堆删除此对象吗?

在下面的代码,我认为这是熄灭的主,而不是在堆中的对象本身范围内的指针,但在某些时候如果确实内存被释放此对象的对象的析构函数应该叫什么名字?

我也试过在主加入成员函数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++ singleton destructor
3个回答
3
投票

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

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

没有永远做一个对象,因为psingleton = NULL总是被强制转换为false。你想,而不是什么是if (psingleton == NULL) {

与修复,在MSVC输出对我来说是:

单个对象

在析构函数

......这是因为调用Singleton::GetInstance()->DeleteObject();的,不是因为节目已经结束。


我认为这是熄灭的主,而不是在堆中的对象本身范围内的指针,但在某些时候如果确实内存被释放此对象的对象的析构函数应该叫什么名字?

你是对的。堆中的对象不出去的范围,并没有析构函数只是从程序结束调用。


2
投票

我的教练说,我们并不需要删除堆上创建一个单独的对象,因为当超出范围的内存被释放,并自动删除。

难道编译器将静态对象的不同,我们并不需要担心从堆删除此对象吗?

你的教练是错误的。如果它是专门破坏(例如,使用相应的操作员new)动态分配对象(例如,与操作者delete创建)将只被释放。

如果指针指向的对象是一个静态变量没关系。

什么发生,最现代的操作系统,是在程序终止(正常或异常)操作系统将回收程序所使用的内存。然而,这不会导致动态分配对象的析构函数的调用。如果依靠析构函数被调用(而不是被回收的存储器),那么你需要确保析构函数的程序结束前被调用。例如,如果一个对象管理系统资源,如一个互斥。

C ++标准不要求动态分配对象作为程序终止时被释放。这做回收退出过程中回收内存的内存大部分(如果不是全部)现代操作系统(UNIX,Windows和等),不会调用动态分配的对象的析构函数。

也有操作系统不打扰收回终止程序的内存 - 虽然这样的系统的使用,现在是不常见的,这在它们上面运行的程序需要进行专门设计,以确保他们正确释放所有动态分配的对象。

有,当然,能够被用于确保动态分配对象技术被释放(例如存储在一个std::unique_ptr指针这些对象)。静态std::unique_ptr<T>将被销毁的程序终止,它的析构函数会自动销毁它所管理的任何动态分配的对象。 (有,当然,如何防止这种情况的发生,如通过调用std::abort())。


1
投票

我想你教练是错误的,上面的代码会导致单一对象的内存泄漏

© www.soinside.com 2019 - 2024. All rights reserved.