我应该释放析构函数中的所有成员(动态分配的)吗?

Should I free all the members (which were dynamically allocated) in destructor?

#include <iostream>
#include <vector>
using namespace std;
#define l(x) cout << (#x) << " : " << x << endl;
#define forf(x, fromY, Step, toZ) for(double x = fromY; x <= toZ; x+=Step)

class Particle {
public:
    Particle() {
        totalYield = winRate = 0;
    }
    ~Particle() {
        //cout << " Particle destructor were called";
        args.~vector();
    }
    Particle(double* inputArgs, int nSize) 
    :args(nSize)
    {
        for (int i = 0; i < nSize; i++) {
            args[i] = inputArgs[i];
        }
        totalYield = winRate = 0;
    }
    double GetAt(int i = 0) {
        return args[i];
    }

protected:
    double winRate, totalYield;
    unsigned int winCount, totalCount;
    vector<double> args;
};

您好, 我从课本上了解到,在使用动态分配后,我必须释放所有内存。

据我了解,析构函数默认调用其成员的析构函数(没有任何命令)

  1. 我的第一个问题是如果我使用动态分配 class 中的数组,我应该在析构函数中释放它们吗?。这是 不清楚,因为解构函数自然称其为成员 析构函数作为默认值。这次执行是否释放了 动态分配内存?
  2. 我的第二个问题是:我应该调用成员向量的 class 的析构函数中的析构函数?(参见 args.~vector(); // 我应该这样做吗?这样对吗?)

if I use the dynamically allocated array in class, should I free them in deconstructor?

如果您的 class分配内存,那么您的class应该释放它。如果动态数组 class 分配内存,则该动态数组 class 应该释放内存。

the deconstructor naturally calls it's members' deconstructors as a default. does this execution free the dynamically allocated memory?

让我们看看std::vector的析构函数的引用是怎么说的:

Destructs the container. The destructors of the elements are called and the used storage is deallocated.

原来是的,内存确实释放了。这是一个很好的容器设计。


should I call member vector's deconstructor in class's deconstructor? (See args.~vector(); // should I do this? is this right?)

不,你不应该,这是不对的。因为 - 如您所说 - "the deconstructor calls it's members' deconstructors as a default"。澄清一下,成员 总是 在析构函数主体执行后被销毁。如果你还在的析构函数体内调用一个成员的析构函数,那么那个析构函数会被调用两次,这是非常糟糕的。

隐式析构函数是正确的,足以满足您的 class。您不需要明确定义它。

几乎不需要显式调用析构函数。当超级对象被销毁时,会自动调用基础子对象和成员的析构函数。数组元素的析构函数在数组被销毁时自动调用。当自动对象超出范围时,自动对象的析构函数被自动调用。在 delete 表达式上自动调用动态对象的析构函数。在 main 函数 returns 之后发生的静态析构期间,会自动调用静态对象的析构函数。在 none 这些情况下,是否需要显式调用析构函数。

唯一需要显式调用析构函数的情况是在对象存储被其他对象重用的情况下 - 这是一种您还不需要学习的高级技术。