【问题标题】:destructors of base and derived classes c++ [duplicate]基类和派生类c ++的析构函数
【发布时间】:2014-08-08 15:06:30
【问题描述】:

我检查了这段代码,我在函数 func() 的末尾看到了 基类的析构函数被调用了两次。 我不明白为什么? 谢谢你。。

class base  {
public:
    base(){cout << "ctor of base\n";}
    ~base(){cout << "d-ctor of base\n";}
};
class derived: public base 
{
public:
    derived(){cout << "ctor of derived\n";}
    ~derived(){cout << "d-ctor of derived\n";}
};
void func(base ob)
{
    cout << "inside func\n";
}
void main()
{
    derived ob; 
    func(ob);

    system("pause");
}

【问题讨论】:

  • @Csq 是的,它被切片了,但这并不能解释 两次 调用~base()
  • 当多态性受到威胁时,不要忘记虚拟析构函数。这里~base() 应该是virtual ~base()
  • @Angew 我已经写了一个更详细的答案。
  • 你确定这两种破坏都发生在“函数func()”的末尾,即调用system()之前?

标签: c++ inheritance destructor


【解决方案1】:

像这样重构你的基类:

class base  {
public:
    base(){cout << "ctor of base\n";}
    base(const base&) {cout << "copy-ctor of base\n";}
    ~base(){cout << "d-ctor of base\n";}
};

将发出以下输出:

ctor of base
ctor of derived
copy-ctor of base
inside func
d-ctor of base
d-ctor of derived
d-ctor of base

非常清楚地显示您在 func 中的基本变量被复制然后销毁。

【讨论】:

  • 好的,我用另一个编译器试了一下,我发现基础 d-ctor 只调用了一次。这意味着我自己的编译器有问题
【解决方案2】:

base 按值传递给func。 这意味着将创建ob 的切片副本。

这将被销毁以及ob 本身。 obderived::~derived)的析构函数会自动调用基类的析构函数。

因此,base 析构函数被调用了两次。

【讨论】:

    【解决方案3】:

    当您调用函数时,您按值获取参数。因此,您在func 中创建了一个base 类型的局部变量。

    当你从func返回时,局部变量被销毁,所以ob的析构函数(类型为base)被调用。

    你必须通过引用或指针传递多态类型。

    这称为切片问题。详情见this链接。

    【讨论】:

    • 仍然不考虑第二次调用~base();或者那是从哪里来的?
    • @Angew 这是个好问题,我cannot reproduce 那。
    猜你喜欢
    • 2015-04-16
    • 2016-12-20
    • 1970-01-01
    • 2015-08-18
    • 2015-02-24
    • 2021-02-14
    • 1970-01-01
    • 2015-11-03
    • 2011-02-14
    相关资源
    最近更新 更多