为什么派生构造函数需要基础析构函数?

时间:2014-09-25 10:33:28

标签: c++

class A{
  public:
   A();
  private:
   ~A();
};

class B:public A{
  public:
    B(){};
  private:
   ~B();
};

int main()
{
  return 0;
}

我遇到了这样的编译错误:

test.cpp: In constructor 'B::B()':
test.cpp:5:4: error: 'A::~A()' is private
test.cpp:10:8: error: within this context

我知道派生的构造函数需要调用基础析构函数,因此我将A::A()设置为public。 但是,为什么编译器会抱怨它需要公开A::~A()

3 个答案:

答案 0 :(得分:4)

我能找到的最接近的规格是here - 12.4.10 class.dtor

  

...如果是类类型或数组的对象,程序就会形成错误   声明并且无法访问该类的析构函数   在宣言时。

class B无法访问private: ~A(),但隐式声明class A因为它是基类(它几乎与首先声明相同)成员变量 - 除空基优化外。)

我不是语言律师,也不是母语,但是无法访问的基类析构函数似乎是问题,上面可以解释为什么错误指向构造函数B() (编译器可以在真正需要时执行检查,而不是之前执行检查。)

析构函数~A()需要至少成为protected的{​​{1}}或B朋友。

答案 1 :(得分:3)

C ++标准委员会核心工作组缺陷报告1424(由DanielKrügler于2011-12-07提交)说:

  

当子规则的析构函数不可访问时,当前规范似乎并未说明是否允许/要求/禁止实现。

通过添加可能被调用的析构函数的概念,在C ++ 14中修复了这个问题。目前的标准草案部分 12.6.2(10)表示:

  

在非委托构造函数中,可能会调用每个直接或虚拟基类的析构函数以及类类型的每个非静态数据成员(12.4)。

     

[注意:此规定确保在抛出异常时可以为完全构造的子对象调用析构函数(15.2)。 -end note ]

12.4(11)

  

如果调用析构函数,则可以调用 ,如5.3.4和12.6.2中所述。 如果可能调用的析构函数被删除或无法从调用上下文访问,则程序格式不正确。

答案 2 :(得分:0)

将构造函数和析构函数声明为public(如果确保仅由子类调用,则可以保护基类构造函数和析构函数)。构造时的子类具有作为cubobject创建的基类实例,因此构造函数和析构函数的显式或隐式调用都已完成