我有三个名为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();
}
答案 0 :(得分:1)
让A
继承IBinary
,这将使所有孩子都可以用作抽象界面IBinary
。
答案 1 :(得分:1)
您看到此行为的原因很简单,因为A::readb
未声明为virtual
。
由于IBinary::readb
为virtual
,当A
继承A::readb
时,virtual
默认为virtual
。
如果您将readb
添加到virtual
的每个声明中,而不仅仅是第一个声明,那么您的代码会表现得更加一致。出于这个原因,许多C ++代码样式指南要求所有派生类中的所有virtual
方法都被声明为{{1}},即使它们不是祖先基类。
答案 2 :(得分:1)
virtual
定义中的IBinary::readb
会产生重大影响。
当您从IBinary
继承时,层次结构中覆盖readb
中的IBinary
的所有B
也都是隐式虚拟的。因此,虚拟的dispacth就像它应该的那样开始。
如果不这样做,则静态解决呼叫。由于调用位于B::readb
内,因此调用{{1}}。