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

yxyvkwin  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(106)
#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;
}

这是释放dude1内存并销毁对象dude1的正确方法吗?
如果作为默认析构函数,析构函数将执行哪些内存释放和清除操作?
dude1->~Dude();
这段代码是做什么的?

vq8itlhq

vq8itlhq1#

这是释放dude1内存并销毁对象dude1的正确方法吗?
是的,从技术上讲是正确的。
但是,这并不是最好的选择。一个更好的选择是在自动存储中创建Dude对象,而不用担心它的释放/清理,让编译器为你担心,例如:

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

    return 0;
}

如果你必须动态创建对象,至少使用一个像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;
}

如果作为默认析构函数,析构函数将执行哪些内存释放和清除操作?
在这个例子中,什么都没有。
一般来说,当你处理对象时,在 * 分配/解除分配 * 和 * 创建/销毁 * 之间有一个明确的职责分离。首先为对象保留内存,然后在该内存中创建对象。随后,首先销毁对象,然后释放其内存。
当一个对象具有 * 自动存储持续时间 * 时,它的内存被保留在调用作用域(例如,函数/块中的局部变量,类的数据成员等),并且它在该作用域的内存中被创建。当该作用域结束时(例如,函数/块结束,包含的对象被销毁等),作用域对象被自动销毁,并且它的内存被释放。
因此,在您的示例中,Dude的默认 * 析构函数 * 什么也不做,因为它没有要销毁的东西。
Dude有一个int数据成员,该成员是在Dude内使用 * 自动存储持续时间 * 创建的。创建Dude对象时,int的空间将包含在Dude对象的内存分配中,但是在Dude对象在该存储器中被构造之前,int对于使用是无效的。稍后,当Dude对象被销毁时,当调用Dude对象的析构函数时,int变为无效,然后当释放Dude对象的内存时,int的内存消失。
在我上面的第一个例子中,Dude对象具有 * 自动存储持续时间 *,它的作用域是main(),因此编译器在main()的堆栈帧内保留内存来保存Dude对象,然后创建Dude对象当main()退出时,Dude对象超出作用域并被销毁(即调用其析构函数),当堆栈帧被清除时,其内存被释放。
在我上面的第二个示例中,Dude对象具有 * 动态存储持续时间 *。它的作用域是动态内存。new分配动态内存来保存Dude对象,然后创建Dude对象(即调用其构造函数)。稍后,delete销毁Dude对象(即调用其析构函数)并释放new已分配的动态内存。
注意Dude里面的int总是有 * automatic storage duration *,它的作用域是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;
}

相关问题