【问题标题】:Override or remove an inherited constructor覆盖或删除继承的构造函数
【发布时间】:2010-07-01 09:41:39
【问题描述】:

这是一些 C++ 代码:

#include <iostream>
using namespace std;

class m
{
    public:
    m() { cout << "mother" << endl; }
};

class n : m
{
    public:
    n() { cout << "daughter" << endl; }
};

int main()
{
    m M;
    n N;
}

这是输出:

mother  
mother  
daughter

我的问题是我不想在创建N的时候调用m的构造函数,我该怎么办?

【问题讨论】:

    标签: c++ class inheritance


    【解决方案1】:

    AFAIK,您不能删除继承的构造函数。

    您示例中的问题来自不正确的类设计。 构造函数通常用于分配类资源、设置默认值等。 不完全适合用来输出东西。

    你应该放

    n() { cout << "daughter" << endl; }
    

    进入虚函数。

    一般来说 - 如果您需要删除继承的构造函数,那么您可能需要重新考虑/重新设计您的类层次结构。

    【讨论】:

    • +1 但是为了避免让OP误入歧途,也许应该指出ctors不应该调用虚函数。
    • 请注意,对象的动态类型在构建对象时会发生变化。如果您在基本构造函数中调用虚方法,则输出将始终为“基本”,因为在执行该构造函数时,对象 is 是“基本”
    • @stinky472:在 C++ 中,与 Java 不同,在构造函数(或析构函数)中调用虚方法是安全的,只要您知道此时派生类覆盖器将不被考虑。仅当该方法在此级别上是纯虚拟的时,它才是从构造函数/析构函数调用它的未定义行为。另一方面,在 Java 中,您不得在构造函数中调用任何被覆盖的方法,因为这些方法将被分派给尚未初始化的最派生类。
    【解决方案2】:
    class m
    {
    public:
          m(bool init = true) { if (init) cout << "mother" << endl; }
    };
    
    
    class n : m
    {
    public:
          n() : m(false) { cout << "daughter" << endl; }
    };
    

    或者如果你不想公开

    class m
    {
    protected:
        m(bool init) { if(init) Init(); }
        Init() { cout << "mother" << endl; }
    
    public:
          m() { Init(); }
    };
    
    class n : m
    {
    public:
          n() : m(false) { cout << "daughter" << endl; }
    };
    

    【讨论】:

      【解决方案3】:

      两种解决方案:

      1. 不要从m 派生n。检查你是否真的有接口重用(你依赖于多态接口)而不是实现重用。在后一种情况下,最好将m* 设为n 的成员,然后仅在需要时创建m 对象。这将是我的首选解决方案。

      2. 您可能不希望调用ms 构造函数,因为它做了您不想要的事情。将您不想执行的代码从ms 构造函数中移出到专用的init() 函数或类似函数中,然后根据需要调用它。我不推荐这样做,因为你最终会得到一个有状态的界面。

      【讨论】:

        【解决方案4】:

        构造函数永远不会被继承。发生的情况是 C++ 生成了一个默认的 nullary 构造函数,该构造函数初始化基类和类类型的成员。基类总是被初始化并且没有办法阻止这种情况,所以如果你不希望基类的构造函数被调用,就不要从基类继承。

        【讨论】:

          【解决方案5】:

          任何类的对象都包含其所有超类的子对象。并且所有这些必须在构建主对象之前构建。此构造的一部分是调用基类构造函数之一,不能省略。只能选择要调用的构造函数。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-31
            • 2016-01-27
            • 2014-09-25
            • 2011-10-03
            • 2014-02-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多