C++:为什么它不调用析构函数?
C++: why it doesn't call a destructor?
我在代码中使用了额外的括号。我想在局部变量作用域结束后应该调用析构函数,但它的工作方式不是这样的:
class TestClass {
public:
TestClass() {
printf( "TestClass()n" );
}
~TestClass() {
printf( "~TestClass()n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
它输出:
TestClass()
所以它不调用TestClass的析构函数,但为什么呢?如果我手动调用它(删除测试),它会调用析构函数,对吧。但是为什么在第一种情况下它不调用析构函数呢?
TestClass *test = new TestClass();
您使用new
来创建一个动态分配的对象(很可能放置在堆上)。此类型的资源需要由您手动管理。通过管理,您应该在使用完delete
之后在其上使用它
{
TestClass *test = new TestClass();
// do something
delete test;
}
但是,就大多数目的和意图而言,您只需要使用自动存储对象,这就省去了手动管理对象的麻烦。它也很可能具有更好的性能,尤其是在短寿命对象中除非你有充分的理由不使用它们,否则你应该一直喜欢使用它们。
{
TestClass test;
// do something
}
然而,如果您需要动态分配对象或指针的语义,那么最好使用某种机制来为您封装对象/资源的删除/释放,这也为您提供了额外的安全性,尤其是在使用异常和条件分支时。在您的情况下,如果您使用std::unique_ptr
会更好。
{
std::unique_ptr<TestClass> test(new TestClass());
// auto test = std::make_unique<TestClass>(); in C++14
// do something (maybe you want to pass ownership of the pointer)
}
下面是一个相关的链接,可以帮助您决定是使用自动存储对象还是动态分配对象:为什么C++程序员应该尽量减少';新';?
因为您有一个指向动态分配对象的指针。只有指针超出了作用域,而不是它所指向的对象。必须对指针调用delete
才能调用指针对象的析构函数。
尝试使用自动存储对象:
{
TestClass test;
}
在这里,析构函数将在退出作用域时调用。
不鼓励在C++中使用指向动态分配对象的原始指针,因为它很容易导致资源泄漏,如代码示例中所示。如果确实需要指向动态分配对象的指针,那么明智的做法是使用智能指针来处理它们,而不是尝试手动处理它们的销毁。
这个答案已经足够好了,但只是增加了一些内容。
我看你已经用Java
编码了。在C++
中,在堆栈中创建变量/对象不需要关键字new
。实际上,当您使用关键字new
时,您的对象是在堆中创建的,并且在离开作用域后不会销毁。要销毁它,您需要在您的情况下调用delete
delete test;
在像您这样的结构中,离开作用域后,您只会丢失指向对象的指针,所以离开作用域之后,您不能释放内存并调用析构函数,但最终OS会在执行exit()
指令后调用析构因子。
总结C++
!=Java
- 什么时候调用析构函数
- C++-明确何时以及如何调用析构函数
- C++ 防止在映射中放置()时调用析构函数
- 调用析构函数以释放动态分配的内存
- C++:使用方法调用析构函数的顺序是什么?
- 向量推回调用析构函数时调用析构函数
- 如何在调用析构函数时优雅地停止/销毁带有阻塞调用C++线程?
- C++,我应该调用析构函数吗?
- 如何获取有关在 Clang LibTooling 中调用析构函数的信息?
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 为什么这里不调用析构函数
- 在调用 std::bind 的产品后意外调用析构函数
- 为什么在传递给函数而不是构造函数时调用析构函数?
- 如何在C++中调用析构函数
- 为什么为未删除的对象调用析构函数?
- 调用析构函数时出错
- C++ 在不释放内存的情况下调用析构函数
- 为什么在运算符删除中不调用析构函数?
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 在 postOrderDelete 上调用析构函数时引发的异常