适当的继承设计

时间:2013-08-01 19:10:23

标签: c++ inheritance

我有三个名为A,B和C的类.B继承自A和C继承自B.(A - > B - > C)。

我还有一个名为IBinary的抽象基类。我想让所有的类都实现IBinary接口。当我使A类继承自IBinary时,我的代码输出为C::readb。当A类不从IBinary继承时,输出为B:readb

让我的三个类订阅同一个界面的正确方法是什么?如果我只从接口类继承顶级类(A),我将需要重构我的代码,以便我没有像上面那样的解决问题。

如果我明确地让所有类都继承自接口类,那么我将拥有一个更复杂的类层次结构,并且更接近于拥有一颗死亡之钻。


#include <iostream>

class IBinary {
public:
    virtual void readb( std::istream& in ) = 0;
};

// Basic A -- change whether this inherits from IBinary
class A : public IBinary {
public:
    A() {};

    void readb( std::istream& in ) {}
};

// Specialized A
class B : public A {
public:
    B() {};

    void load() {
        this->readb(std::cin);        // <-- which readb is called?
    }
    void readb( std::istream& in ) {
        std::cout << "B::readb" << std::endl;
    }
};

// Specialized B
class C : public B {
public:
    C() {};

    void readb( std::istream& in ) {
        std::cout << "C::readb" << std::endl;
    }
    void foo() {
        B::load();
    }
};

int main() {
    C c;
    c.foo();
}

3 个答案:

答案 0 :(得分:1)

A继承IBinary,这将使所有孩子都可以用作抽象界面IBinary

答案 1 :(得分:1)

您看到此行为的原因很简单,因为A::readb未声明为virtual

由于IBinary::readbvirtual,当A继承A::readb时,virtual默认为virtual

如果您将readb添加到virtual的每个声明中,而不仅仅是第一个声明,那么您的代码会表现得更加一致。出于这个原因,许多C ++代码样式指南要求所有派生类中的所有virtual方法都被声明为{{1}},即使它们不是祖先基类。

答案 2 :(得分:1)

virtual定义中的IBinary::readb会产生重大影响。

当您从IBinary继承时,层次结构中覆盖readb中的IBinary的所有B也都是隐式虚拟的。因此,虚拟的dispacth就像它应该的那样开始。

如果不这样做,则静态解决呼叫。由于调用位于B::readb内,因此调用{{1}}。

相关问题