【发布时间】:2018-11-24 16:22:30
【问题描述】:
我想在 C++ 中显式调用对象的析构函数来销毁该对象。
这只是一个简单的程序,用于试验编程语言的特性。我有一个将内部数据成员设置为 1 的默认构造函数,以及将内部数据成员设置为参数的重载构造函数,以及一个显示刚刚销毁对象的内部数据成员的析构函数。还有一个打印内部数据成员的函数。
#include <iostream>
using std::cout;
using std::endl;
class myClass {
public:
myClass()
{
i = 1;
cout << "default ";
cout << "constructor called with " << this->i << endl;
}
myClass(int i)
{
this->i = i;
cout << "constructor called with " << this->i << endl;
}
~myClass()
{
cout << "object " << i << " destroyed!" << endl;
}
void printData()
{
cout << "object's data is " << i << endl;
}
private:
int i; // private data member
};
int main() {
myClass a;
myClass b;
myClass c(8);
a.printData();
b.printData();
c.printData();
/* I want to explicitly destroy object b. */
b.~myClass();
b.printData();
/* all the destructors get called when the objects go out of scope */
return 0;
}
我的推理是这样的:我认为析构函数导致对象被销毁,所以它不再存在于内存中。在我显式调用析构函数之后,我应该不再能够再次使用该对象,因为它已被销毁。但是,我可以调用对象的函数并打印内部数据成员的值。手动调用析构函数是否无法销毁对象?这里发生了什么? 输出:
default constructor called with 1
default constructor called with 1
constructor called with 8
object's data is 1
object's data is 1
object's data is 8
object 1 destroyed!
object's data is 1
object 8 destroyed!
object 1 destroyed!
object 1 destroyed!
调用析构函数会破坏对象,还是调用析构函数是破坏对象的结果?
【问题讨论】:
-
“请注意,直接为普通对象(例如局部变量)调用析构函数会在作用域结束时再次调用析构函数时调用未定义的行为。”来自:en.cppreference.com/w/cpp/language/destructor所以基本上不要这样做。
-
您可以安全地手动调用析构函数的唯一时间是使用placement-new 构造对象时,在您的任何示例中都不是这种情况。如果您想要确定性控制对象何时被销毁,请将其放在您控制的范围内,或使用
new/delete(或智能包装器)。但无论哪种方式,一旦一个对象被破坏,访问它的成员就不再安全了。所以在调用~myClass()之后调用printData()是未定义的行为。 -
调用析构函数不会释放内存。此外,即使确实如此,仅仅因为您释放了内存,它也不一定会消失。它可能会流连忘返。
-
调用析构函数是销毁对象,还是调用析构函数是销毁对象的结果?
-
手动调用析构函数不会销毁/释放对象。你应该使用删除。
delete b;在你的情况下。您可能不想手动调用 d'tor,请考虑重新构建您的对象结构以避免这种情况。
标签: c++ oop destructor