析构函数和delete() 哪个先出现?C++

Xfc*_*ce4 6 c++ destructor new-operator dynamic-memory-allocation delete-operator

该网站上的许多答案都提到delete()调用析构函数。但下面的示例代码似乎delete()在析构函数内部调用。当对象在堆栈和堆中初始化时,delete() 的正确用法是什么?

点击查看来源。

#include <iostream>
using namespace std;
 
class SmartPtr {
    int* ptr; // Actual pointer
public:
    // Constructor: Refer https:// www.geeksforgeeks.org/g-fact-93/
    // for use of explicit keyword
    explicit SmartPtr(int* p = NULL) { ptr = p; }
 
    // Destructor
    ~SmartPtr() { delete (ptr); }
 
    // Overloading dereferencing operator
    int& operator*() { return *ptr; }
};
 
int main()
{
    SmartPtr ptr(new int());
    *ptr = 20;
    cout << *ptr;
 
    // We don't need to call delete ptr: when the object
    // ptr goes out of scope, the destructor for it is automatically
    // called and destructor does delete ptr.
 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 9

当析构函数SmartPtr获得控制权时

 ~SmartPtr() { delete (ptr); }
Run Code Online (Sandbox Code Playgroud)

它的主体被执行。在主体内使用了执行的删除操作符。如果指针ptr指向类类型的对象,则在释放该对象的动态分配的内存之前将依次调用该类的析构函数。

这是一个演示程序。

#include <iostream>

int main()
{
    struct A
    {
        ~A() { std::cout << "A::~A() called\n"; }
    };

    struct B
    {
        B() : ptr( new A ) {};
        ~B()
        {
            std::cout << "B::~B() called\n";
            delete ptr;
        }
        A *ptr;
    };

    { 
        B b; 
    }

    std::cout << "That is all!\n";
}
Run Code Online (Sandbox Code Playgroud)

程序输出是

B::~B() called
A::~A() called
That is all!
Run Code Online (Sandbox Code Playgroud)

如果要在类的析构函数中删除B此语句

delete ptr;
Run Code Online (Sandbox Code Playgroud)

那么B类的对象就会产生内存泄漏,因为该类动态分配的对象A不会被销毁,并且它们占用的内存也不会被释放。