覆盖或删除继承的构造函数

问题描述 投票:0回答:6

这是一些 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
6个回答
16
投票

AFAIK,您无法删除继承的构造函数。

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

你应该放

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

进入虚函数。

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


6
投票
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; }
};

0
投票

两种解决方案:

  1. 不要从

    n
    派生出
    m
    。检查您是否确实具有接口重用(您依赖于多态接口)而不是实现重用。在后一种情况下,更喜欢使
    m*
    成为
    n
    的成员,然后仅在需要时创建
    m
    对象。这将是我的首选解决方案。

  2. 您可能不希望调用

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


0
投票

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


0
投票

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


0
投票

正如其他人提到的,您无法覆盖它。但是您可以通过创建一个不执行任何操作的构造函数重载并显式调用它来轻松绕过它:

class m
{
    public:
    m() { cout << "mother" << endl; }
    m(int) {} // Do nothing
};

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

输出:

daughter
© www.soinside.com 2019 - 2024. All rights reserved.