【问题标题】:Constructor and Destructor Inheritance构造函数和析构函数继承
【发布时间】:2011-12-27 13:50:13
【问题描述】:

我相信base class中的ConstructorsDestructors不能被基类的derived classes继承。我的理解是否正确。

【问题讨论】:

    标签: c++ inheritance derived-class base-class


    【解决方案1】:

    我想这就是你要找的东西?您可以通过将以下内容添加到类构造函数来调用超类构造函数

    SubClass(int foo, int bar)
        : SuperClass(foo)
    

    一个完整的例子可以在这里找到What are the rules for calling the superclass constructor?

    【讨论】:

    • 谢谢@Niels。但我只想知道构造函数和析构函数是否继承?
    • @LinuxPenseur:不,他们不是。每个类都有自己的构造函数和析构函数(包括复制构造函数)。如果你不提供构造函数或析构函数,编译器会默认为你生成它们。
    【解决方案2】:

    相反,派生类的每个构造函数都会调用基类 [super-] 的构造函数。派生类的每个析构函数都在基 [super-] 类的析构函数之前调用。

    继承涉及类,而不是函数或构造函数。

    【讨论】:

    • 继承非常关注函数,因为它们是被继承的。
    • Class-es 比成员函数被继承的更多。成员函数可以专门化(例如,重新定义,并使用虚拟间接调用)。
    • 一个类从它的基类继承所有函数。您可以将它们视为子类本身已定义它们。它继承了功能。您还可以调用从基类继承的非虚函数。
    • 我认为正确的术语是该类继承自其所有基类。
    • 一个类从它的基类继承,但它从基类继承什么——成员。
    【解决方案3】:

    不,它们是遗传的。一方面,析构函数总是被继承并以与创建相反的顺序被调用。例如,如果我们有 foobarxyzzy 类:

    class foo { ... };
    class bar : public foo { ... };
    class xyzzy : public bar { ... };
    

    然后,如果你销毁一个 xyzzy 类的对象,析构函数将按以下顺序调用:~xyzzy()~bar(),最后是~foo()

    构造函数也总是被继承的,但它们不能被直接调用。您必须在构造函数初始化列表中使用它们,否则将调用默认构造函数(默认构造函数是不带参数的构造函数)。例如,假设我们有以下类:

    class foo {
    public:
        foo();
        foo (int _value);
    }
    
    class bar : public foo {
        int m_value;
    
    public:
        bar (int _value);
    }
    
    bar::bar (int _value)
    {
        m_value = _value;
    }
    

    在这种情况下,当您创建类 bar 的对象时,会调用 foo 的构造函数,但它是默认构造函数 (foo())。接受参数foo (int _value) 的构造函数永远不会被调用。但是如果我们将 bar (int _value) 构造函数的定义更改为:

    bar::bar (int _value)
        : foo (256 - _value), m_value (_value)
    {
    }
    

    然后将调用foo (int _value),而不是默认构造函数。

    【讨论】:

    • 查看您的答案与下面cpx 的评论相矛盾。我相信cpx 所说的是正确的。您能否验证@Septagram
    • -1: Constructors are not inherited,析构函数也是如此。
    • 如果析构函数不是虚拟的并且你正在删除一些基类指针怎么办?
    • 这是一个信息丰富的答案。问题仅仅是它错误地使用了“继承”一词吗?
    【解决方案4】:

    正如this question 解释的那样,构造函数不是继承的。这同样适用于析构函数。

    【讨论】:

      【解决方案5】:

      你的理解是正确的。例如,如果您有

      class Base
      {
        Base(int i) {}
      };
      
      class Derived: public Base {};
      
      Derived d(3);
      

      这不会编译,因为 Base 构造函数没有被继承。 请注意,如果可能,编译器会创建默认构造函数和复制构造函数,并调用相应的基类构造函数,因此对于那些构造函数,它看起来好像它们是被继承的。

      【讨论】:

        猜你喜欢
        • 2012-11-14
        • 2016-03-24
        • 2014-11-22
        • 1970-01-01
        • 2013-06-01
        • 2023-04-03
        相关资源
        最近更新 更多