【问题标题】:Explantation about inheritance关于继承的解释
【发布时间】:2013-04-28 09:39:33
【问题描述】:

我有两个类,而B 派生A。

我创建了一个指向A 的指针,称为:a2。请查看我的main 函数。

这条线有什么作用?

a2 = new B();

为什么我删除a2时,只激活了A的析构函数?

#include <iostream>
using namespace std;

class A {
    int num;
  public:
    A() { cout << "constructor of A\n"; }
    void set_num(int new_num) { cout << "set_num of A" << endl; num = new_num; }
    void print() { cout << "print of A: ";  cout << num << endl; }
    ~A() { cout << "destructor of A\n"; }
};

class B: public A {
    int num;
  public:
    B() { cout << "constructor of B\n"; }
    void set_num(int new_num) { cout << "set_num of B" << endl; num = new_num; }
    void print() { cout << "print of B: ";  cout << num << endl; }
    ~B() { cout << "destructor of B\n"; }
};

void main() {
    A *a2;
    a2 = new B();
    delete a2;
}

这是输出:

constructor of A
constructor of B
destructor of A

感谢每一个帮助!

【问题讨论】:

  • 如果您将a2 的类型从A * 更改为B *(它的实际,最具体的类型),那么这将按预期工作。此外,main() 必须返回 int,并且不 void。
  • @H2CO3,好的,非常感谢!

标签: pointers inheritance constructor destructor derived-class


【解决方案1】:

首先让你的析构函数虚拟化...

虚拟~A()... 虚拟~B()...

看这里:When to use virtual destructors?

【讨论】:

    【解决方案2】:

    如果要通过指向基子对象的指针删除对象,则基类的析构函数必须是虚的:

    class A
    {
    public:
        virtual ~A() { /* ... */ }
        // ...
    };
    

    (这将自动使所有派生类析构函数也成为虚拟的,因此您不必在那里拼写出来。)

    原因是 C++11 标准的第 5.3.5/3 条:

    如果要删除的对象的静态类型与其不同 动态类型,静态类型应该是要删除的对象的动态类型的基类, 静态类型应具有虚拟析构函数,否则行为未定义。

    我相信你可以想象为什么虚拟析构函数是,但举一个简单的例子,想象一下指向基址的指针(如你的a2)甚至不必在数字上与指向的指针相同实际对象-但您需要确切的指针来释放内存。所以很明显,在找出正确地址的过程中需要一些魔法。虚拟析构函数结合了这种魔力。

    【讨论】:

      【解决方案3】:

      所以这里最简单和最方便的解决方案是使用虚拟析构函数,但让我也展示另一种解决方案:帮助编译器。 类型推断在这里很有用 - 如果您将对象声明为尽可能具体的类型,你会得到预期的行为:

      int main()
      {
          B *a2;
          a2 = new B();
          delete a2;
      }
      

      输出

      constructor of A
      constructor of B
      destructor of B
      destructor of A
      

      另外,main() 应该返回 int,而不是 void。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多