C++:为什么它不调用析构函数?

C++: why it doesn't call a destructor?

本文关键字:调用 析构函数 为什么 C++      更新时间:2023-10-16

我在代码中使用了额外的括号。我想在局部变量作用域结束后应该调用析构函数,但它的工作方式不是这样的:

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