是否可以继承接口的实现而不为每个实现实现它?
在上图IBase
和Ichild
中,只有纯虚方法的类和Base
实现IBase
和Child
的方法实现了IChild
。
现在以某种方式Child
可以通过IBase
继承Base
方法的实现,以便Child
不必自己实现这些方法吗?
我试图像这样实现它:
struct IBase {
virtual void do_something_Base() = 0;
};
struct IChild : public virtual IBase {
virtual void do_something_Child() = 0;
};
struct Base : public virtual IBase {
virtual void do_something_Base() { //implementation IBase method
//do sth
}
};
struct Child : public Base , public IChild {
virtual void do_something_Child() { //implementation IChild method
//do sth
}
};
int main() {
IBase* B = new Child;
B->do_something_Base();
delete B;
return 0;
}
此代码的问题是copiler发出警告:
警告C4250:'孩子':继承' Base :: Base :: do_something_Base'通过支配地位
此外,程序在delete B
行崩溃。
(如果我使用IChild* B
代替IBase* B
,程序不会崩溃。为什么会这样?)
提前致谢
答案 0 :(得分:2)
答案 1 :(得分:1)
继承通过支配只是一个警告,可以在这里安全地忽略,因为支配给你正确的方法覆盖。
但删除时的崩溃是因为通过一个类和派生类指向对象的指针不需要具有相同的表示(*)。并且您忘记在IBase
和IChild
中添加虚拟析构函数,而强烈建议使用可继承类,并且必须允许通过指向@Angew所述的继承类的指针进行删除。
如果你有充分的理由不拥有虚拟析构函数(即使我无法想象),你必须在调用delete之前将其强制转换为Child *
。此外,由于IBase
是虚拟的,您必须使用dynamic_cast
:
delete dynamic_cast<Child>(B);
另一种方法是保留通过new返回的原始指针并将其删除,而不是使用转换为IBase*
:
Child* C = new Child;
IBase *B = C;
B->do_something_Base();
delete C; // deleting original pointer is safe
(*)只是为了确保,只需添加到您的代码中:
std::cout << "IBase*:" << B << " Child*:" << dynamic_cast<Child>(B) << std::endl;