【问题标题】:Constructors inheritance vs methods inheritance in C++ objectsC++ 对象中的构造函数继承与方法继承
【发布时间】:2014-12-27 12:47:02
【问题描述】:

在 C++ 下有没有办法让对象方法继承像构造函数继承一样起作用? 让我们有以下内容:

(myclass.h)

class B{
public:
    B();

    void doSomething();
};

class A : public B{
public:
    A();

    void doSomething();
}

(myclass.cpp)

B::B()
{
    executeBCode();
}

void B::doSomething()
{
    executeBCode();
}

A::A : B()
{
    executeACode();
}

void A::doSomething()
{
    executeACode();
}

调用 A 构造函数时会发生什么,我执行executeBCode(),然后执行executeACode()。在 A 对象上调用 doSomething() 方法时,我只执行 executeACode(),因为它已被覆盖。 有没有办法让方法的继承行为类似于构造函数的继承,因此同时执行派生代码和基础代码? 我遇到这个问题是因为我需要代码中的基类为其派生类做一些事情,而且派生类应该执行自己的指令:这只是在派生类上调用doSomething() 函数。 例如,在 A 上调用 closeAll() 方法可能就是这种情况,其中基类关闭其自己的基对象并派生其特定的东西。

【问题讨论】:

  • 您可以将对B::doSomething(); 的调用添加到void A::doSomething() 函数。否则调查template method pattern
  • 在 A 上调用 B::doSomething(); 意味着继承无效。我无法理解为什么它没有在 C++ 语言中使用基本方法上的关键字实现。也许在其他编程语言中也是如此......
  • doSomething 没有被覆盖,它只是被另一个同名的函数隐藏了。覆盖意味着替换一个虚函数,而你没有虚函数。
  • “意味着继承在无用” 这是一个完全愚蠢的说法。继承有很多用途,它不做你想做的一件事的事实并不意味着它“无用”。基类必须被创建和销毁,因此对其构造函数和析构函数的调用有时会隐式发生。基类函数必须被调用是不正确的,因此当派生类中碰巧有具有相同签名的函数时,对它们的调用不是隐式的,您需要显式调用基函数.
  • "表示继承在无用" ...解决这个具体情况。由于建议的解决方案之一是直接调用基本函数

标签: c++ inheritance


【解决方案1】:

这是不可能的,但是您可以通过以下方式使用Non-virtual interface idiom 来实现足够接近的目标:

class A {
public:
    void someFunction() {
        //put the base's code here
        someFuncImpl();//Calls the private function here
        //or here, as you see fit
    }        
private:
    virtual void someFuncImpl();//potentially pure: = 0;
};

然后在另一个班级:

class B : public A {
private:
    virtual void someFuncImpl() {
        //Derived's code goes here
    }
};

这样,当您在类B 上调用someFunction() 时,您每次都会执行派生类的代码基类的代码。

这并不像构造函数那样简单,但我认为这是你能得到的最接近和最简单的方法。作为奖励,您可以选择在派生代码之前或之后运行基础代码。

【讨论】:

  • 没有,但我忘记将B 声明为public A。你不需要在B 中声明someFunction(),因为它继承了A,它也有成员函数。
【解决方案2】:

如果我在这里理解您的意图,则无法直接使用该语言(可能是其他语言)执行此操作。有两种替代机制/技术可用于实现类似结果。

从派生类的函数调用基函数会起作用;

void A::doSomething()
{
    B::doSomething();
    executeACode();
}

使用template method pattern(在 C++ IO 流库中使用),也称为NVI - non virtual interface,也可以使用;

class B {
    void executeBCode();
    virtual void doSomethingImp() = 0; // or not pure
public:
    void pubDoSomething() { // public facing
        executeBCode(); // order these as required
        doSomethingImp();
    }
};

class A {
    void executeACode();
    void doSomethingImp() override // internal implementation
    {
        executeACode();
    }
};

【讨论】:

  • 在最后一个示例中,调用A.doSomething() 会导致只执行executeACode();
【解决方案3】:

在构造函数和析构函数之外没有内置机制。

您可以得到的最接近的方法是自己调用基本方法,或使用template method pattern

class B{
public:
    B();
    void doSomething();
};

class A : public B{
public:
    A();
    void doSomething()
    {
       B::doSomething();
    }
}

【讨论】:

  • 我认为调用基本函数的示例会大大增强这个答案。
猜你喜欢
  • 2014-04-14
  • 2015-06-21
  • 2017-08-09
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
相关资源
最近更新 更多