是否可以继承接口的实现

时间:2015-09-25 13:24:53

标签: c++ oop inheritance interface

是否可以继承接口的实现而不为每个实现实现它?

enter image description here

在上图IBaseIchild中,只有纯虚方法的类和Base实现IBaseChild的方法实现了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,程序不会崩溃。为什么会这样?)

提前致谢

2 个答案:

答案 0 :(得分:2)

我一直在项目中使用类似的设置,它对我有用。它应该足以执行以下操作: 给IBase一个虚拟的析构函数。能够通过指向基类的指针删除虚拟析构函数是必需的。 为了安全起见,也可以从IChild中获取Child。由于I-class没有数据,因此将它们用作非虚拟基础是没有意义的。 禁用警告,因为它基本上告诉编译器正在执行您希望它执行的操作(实现是从正确的基类继承)。

答案 1 :(得分:1)

继承通过支配只是一个警告,可以在这里安全地忽略,因为支配给你正确的方法覆盖。

但删除时的崩溃是因为通过一个类和派生类指向对象的指针不需要具有相同的表示(*)。并且您忘记在IBaseIChild中添加虚拟析构函数,而强烈建议使用可继承类,并且必须允许通过指向@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;