【问题标题】:Should I free all the members (which were dynamically allocated) in destructor?我应该释放析构函数中的所有成员(动态分配的)吗?
【发布时间】:2019-02-08 01:32:26
【问题描述】:
#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. 我的第一个问题是如果我使用动态分配的 类中的数组,我应该在析构函数中释放它们吗?。它是 不清楚,因为解构器自然将其称为成员 析构函数作为默认值。这个执行是否释放了 动态分配内存?
  2. 我的第二个问题是:我应该调用成员向量的吗? 类的析构函数中的析构函数?(参见 args.~vector(); // 我应该这样做吗?是这样吗?)

【问题讨论】:

  • 你的类中没有任何东西是显式动态分配的(vector 与动态分配的数组不同;它是一个类似数组的自我管理的东西,所以它会自行清理)。这里没有什么可破坏的;默认的析构函数就可以了。
  • deconstructor -- 这个词是destructor,而不是deconstructor
  • 我应该在类的析构函数中调用成员向量的析构函数吗? -- 你不仅应该在析构函数中这样做,而且你不应该这样做这个在任何地方,除非你使用placement-new
  • 不要尝试手动调用析构函数
  • @ShadowRanger 谢谢!你的意思是我不必调用向量的解构器吗?然后Particle类会自动调用~vector吗?

标签: c++ dynamic-memory-allocation


【解决方案1】:

如果我在类中使用动态分配的数组,我应该在解构器中释放它们吗?

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

解构器自然地将其成员的解构器称为默认值。此执行是否释放动态分配的内存?

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

破坏容器。元素的析构函数被调用,使用的存储空间被释放。

事实证明,是的,内存确实被释放了。这是一个很好的容器设计。


我应该在类的解构函数中调用成员向量的解构函数吗? (参见 args.~vector(); // 我应该这样做吗?对吗?)

不,你不应该,这是不对的。因为 - 正如你所说 - “解构器将其成员的解构器称为默认值”。澄清一下,在执行了析构函数的主体后,成员总是被销毁。如果你在析构函数的主体内也调用了一个成员的析构函数,那么那个析构函数将被调用两次,这是非常糟糕的。

隐式析构函数是正确的,并且对于您的类来说已经足够了。您不需要明确定义它。

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

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

【讨论】:

  • 很详细的回答!谢谢你。除非我动态分配新内存,否则我不会调用成员的析构函数。
  • @AntonioSEO 不,如果您动态分配新内存,也不要调用 成员的析构函数。让delete 表达式调用析构函数。
  • 哦,是的,这就是我想说的。我只会使用删除运算符!谢谢你^^
猜你喜欢
  • 2020-05-25
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 2011-11-05
相关资源
最近更新 更多