【问题标题】:how much does the default destructor do默认析构函数做了多少
【发布时间】:2012-04-14 17:11:29
【问题描述】:

C++ 类中的默认析构函数是否会自动删除未在代码中显式分配的成员?例如:

class C {
  public:
    C() {}
    int arr[100];
};

int main(void) {
  C* myC = new C();
  delete myC;
  return 0;
}

delete myC 会自动释放 myC 的 arr 吗?还是我需要编写 C 的析构函数来明确地做到这一点?

【问题讨论】:

标签: c++ memory-management destructor


【解决方案1】:

构造函数(在没有任何 ctor-initializer-list 的情况下)调用每个子对象的默认构造函数。

因为你没有基类并且你的成员变量是原始类型,所以它什么都不做。

与析构函数相同。你的是隐式编译器生成的,因为你没有声明一个,它会为每个子对象调用析构函数。这也是微不足道的,因为您唯一的子对象是基元的集合。

现在,当您删除该类时,该类的所有内存都将被释放。由于数组嵌入在类中,因此它属于同一内存区域,并且会同时被释放。

【讨论】:

  • @Mark:析构函数没有“默认”区别,因为它们不能被重载。
  • “子对象”是指“数据成员”,确定吗?
  • @Karl:子对象有两种形式:基本子对象和数据成员子对象,我是指两者。我在回答中没有足够清楚地提到基类的可能性吗?
【解决方案2】:

隐式定义的(默认)析构函数将为每个成员调用析构函数。在成员数组的情况下,它会为数组的每个元素调用析构函数。

注意指针没有析构函数;您需要手动删除它们。在提供的示例中,您没有遇到此问题,但需要注意。

【讨论】:

  • 指针有点像 (see here) 的析构函数,虽然很明显它们不会删除它们指向的东西。
  • 等等...你说指针没有析构函数,但我认为 delete 只需要一个指针。你是说默认的析构函数会在数组中的每 100 个整数上调用 delete?
  • @Robz,不-我是说隐式析构函数调用删除,如果您有任何原始指针,则必须自己在显式析构函数中执行此操作成员。
  • delete 仅适用于指针。此类的 100 个int 成员将通过int::~int() 而不是通过delete 销毁。而int::~int() 什么都不做,很简单,就像所有原始类型(包括指针)一样。
  • @Pubby,指针没有析构函数——它们在被删除时调用析构函数。完全不同的东西。
【解决方案3】:

如果你的类/结构包含一个指针,并且你显式地为该指针分配了一些东西来引用,那么你通常需要在 dtor 中写一个匹配的delete。直接嵌入到类/结构中的成员将被自动创建和销毁。

class X { 
    int x; 
    int *y;
public:
    X() : y(new int) {}
    ~X() : { delete y; }    
};

这里 X::x 将被自动创建/销毁。 X::y(或者,从技术上讲,X::y 指向的东西)不会——我们在 ctor 中分​​配它并在 dtor 中销毁它。

【讨论】:

  • X::y 被自动销毁。如果不是析构函数,*(X::y) 会泄漏。 (并且您的样本违反了三/四/五规则)
  • @BenVoigt:是的——问题是关于析构函数的作用,而不是如何编写一个正确处理远程所有权的类。
【解决方案4】:

任何你调用 new 的东西都必须有相应的 delete。如果您没有调用 new 来创建某事物的实例,那么您不必调用 delete。

【讨论】:

  • 恕我直言,你应该很少delete 应用程序代码中的任何内容。相反,尝试为所有成员建立严格的所有权或成员语义,这样自动销毁就可以了。如果失败,智能指针通常是手动指针和delete 的更好替代方案。
【解决方案5】:

您不必编写析构函数。 C++类有默认析构函数,在'return 0'后删除对象回收内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2022-01-09
    • 2014-01-30
    相关资源
    最近更新 更多