正确使用析构函数

Blo*_*nat 4 c++ dynamic-memory-allocation

我刚开始使用C++,现在我有一个非常基本的问题.

我写了两节课:

坐标:

#include <stdio.h>

class Coordinate {
private:
    int x;
    int y;
public:
    Coordinate(int a, int b) {
        x = a;
        y = b;
    };
    void printTest() {
        printf("%d %d\n", x, y);
    };
};
Run Code Online (Sandbox Code Playgroud)

测试:

class Test {
private:
    int q;
    Coordinate *point;
public:
    Test(int a, int b, int c) {
        q = a;
        point = new Coordinate(b, c);
    };
    virtual ~Test() {
        delete point;
    }
};
Run Code Online (Sandbox Code Playgroud)

主功能:

int main() {
    Test *test = new Test(1, 2, 3);
    // ...
    delete test;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的main工作中,我使用了Test班级的一个对象.我编写了自己的Test析构函数,但我不确定这个析构函数是否像预期的那样工作.它是否完全解除了内存的释放test?或者我是否必须对该q属性执行某些操作才能解除分配?

Tob*_*ght 9

你所做的是正确的,就目前而言.Valgrind报道

==28151== HEAP SUMMARY:
==28151==     in use at exit: 0 bytes in 0 blocks
==28151==   total heap usage: 3 allocs, 3 frees, 72,736 bytes allocated
==28151== 
==28151== All heap blocks were freed -- no leaks are possible
Run Code Online (Sandbox Code Playgroud)

您缺少的是编译器为您提供了默认的复制构造函数和赋值运算符.这些将复制指针,而不是创建新的指向值,因此每次复制Test对象时,您将有两个对象,其析构函数将尝试删除相同的存储.这是一个双重免费,它可以毁了你的一天.

为了避免这种情况,C++程序员在编写类时使用Rule of ThreeRule of Five,或者 - 甚至更好 - 使用Zero规则,它表示您不应该执行任何操作,new或者delete除了仅存在于存储中的类之外.


San*_*ela 5

是的,这是 C++ 析构函数的正确用法(您在 Test 中的析构函数不需要virtual关键字,因为您的示例中没有继承)。

根据经验, eachnew后面应该跟 a delete,但是当您使用类和实例化时,它会变得更加微妙。遵循三五法则,当一个类使用动态内存时,你应该重新定义类析构函数来相应地释放,你做到了,太棒了!

在您的程序执行中,当delete test被调用时,它将首先释放 的动态内存point,然后再释放您在主函数中使用 test 属性设置的动态内存。通过这种方式,您不会泄漏内存(是的!)并且您的内存管理已相应完成:)

  • 如果该类旨在继承自 (2认同)