这是释放新对象的正确方法吗?

Dio*_*Dio 0 c++ destructor class

#include <iostream>

class Dude
{
public:
    int age;

    Dude(int age)
    {
        this->age = age;
    }
};

int main(int argc, char* argv[])
{
    Dude *dude1 = new Dude(21);
    std::cout << dude1->age << '\n';

    delete dude1;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是释放对象内存dude1和销毁对象的正确方法吗dude1

如果保留为默认析构函数,析构函数会执行哪些内存释放和清理?

dude1->~Dude();

这段代码的作用是什么?

Rem*_*eau 5

这是释放对象内存dude1和销毁对象的正确方法吗dude1

是的,这在技术上是正确的

但是,这不是最好的选择。更好选择是Dude在自动存储中创建对象,根本不用担心它的释放/清理,让编译器为您担心,例如:

int main(int argc, char* argv[])
{
    Dude dude1(21);
    std::cout << dude1.age << '\n';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您必须动态创建对象,至少使用智能指针,这样std::unique_ptr您就不需要delete手动创建对象,例如:

#include <memory>

int main(int argc, char* argv[])
{
    auto dude1 = std::make_unique<Dude>(21);
    // prior to C++14, use this instead: 
    // std::unique_ptr<Dude> dude1(new Dude(21));

    std::cout << dude1->age << '\n';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果保留为默认析构函数,析构函数会执行哪些内存释放和清理?

在这个例子中,什么也没有。

一般来说,当您处理对象时,分配/释放创建/销毁之间的职责有明确的分离。首先为对象保留内存,然后在该内存中创建对象。随后,该对象先被销毁,然后其内存被释放。

当对象具有自动存储持续时间时,其内存被保留在调用范围内(即函数/块中的局部变量、类的数据成员等),并且它是在该范围的内存中创建的。当该作用域结束时(即函数/块结束、包含的对象被销毁等),作用域对象将自动销毁并释放其内存。

因此,在您的示例中,默认析构函数Dude执行任何操作,因为它没有任何内容可以销毁。

Dude有一个int数据成员,创建时自动存储持续时间Dude为。Dude创建对象时, 的空间int包含在该对象的内存分配中Dude,但只有在该内存中构造int该对象后, 才能使用。Dude后来,当Dude对象被销毁时,int当调用对象的析构函数时, 就变得无法使用Dude,然后intDude对象的内存被释放时, 的内存也消失了。

在上面的第一个示例中,该Dude对象具有自动存储持续时间。它的范围是main(),因此编译器在 的堆栈帧内保留内存main()来保存该Dude对象,然后Dude在该内存中创建该对象(即调用其构造函数)。当main()退出时,Dude对象超出范围并被销毁(即调用其析构函数),并且当堆栈帧被清理时释放其内存。

在上面的第二个示例中,该Dude对象具有动态存储持续时间。它的范围是动态内存。new分配动态内存来保存Dude对象,然后Dude在该内存中创建对象(即调用其构造函数)。随后,delete销毁该Dude对象(即调用其析构函数)并释放已分配的动态内存new

注意int里面Dude总是有自动存储期限。它的作用域是Dude,因此无论何时Dude分配对象,它都会被分配,并且只要Dude对象被释放,它就会被释放。无论是在自动内存(即堆栈)中还是在动态内存(即堆)中。

dude1->~Dude();

这段代码的作用是什么?

它显式调用对象的析构函数,就像任何其他方法调用一样。但是,不要这样做,除了使用 构造的对象placement-new,例如:

int main(int argc, char* argv[])
{
    // FYI, this is not the correct way to ensure the allocated memory
    // is satisfactory for creating an object in it, this is simplified
    // just for demonstration purposes!
    char *buffer = new char[sizeof(Dude)];

    Dude *dude1 = new (buffer) Dude(21);
    std::cout << dude1->age << '\n';

    dude1->~Dude();

    delete[] buffer;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)