【问题标题】:Is it OK to use multiple inheritance if one parent class is an interface?如果一个父类是接口,是否可以使用多重继承?
【发布时间】:2012-05-21 02:54:13
【问题描述】:

如果一个父类是一个接口(只包含带有虚拟析构函数的纯虚函数),是否可以使用多重继承?

我想只暴露接口部分(图中黄色类)以提高编译速度。绿色部分是执行部分。但是CPet应该继承自CAnimal(is-a relationship)和IPet(implement),还有“死亡之钻”:(

接口类(黄色部分)只有纯虚函数和虚析构,所以我通过工厂类创建CDog、CCat时,没有歧义之类的问题。 CDog 有两个 vtable(来自 IDog 和 CPet),但在虚函数表中,点表示相同的函数(CDog 成员函数)。

没有编译错误,没有运行错误……但我担心这个层次结构。 没问题还是有什么问题?

PS:我不想使用“虚拟继承”,因为如果我使用它,我无法通过观察视图查看类成员变量。(我猜这是因为虚拟继承链接到父类,如链接 -列表。)

环境:Visual Studio C++ 2008 或以上。

【问题讨论】:

  • “我不想使用'虚拟继承',因为如果我使用它,我无法通过监视视图查看类成员变量。”假设这是真的(我还没有验证过),也许你应该使用更好的调试器。您不应该仅仅因为调试环境的属性而避免使用语言功能。这就像不使用 std::vector 只是因为它使查看数组变得更加困难。
  • 只有Pets可以Eat?可怜的饥饿的野生动物:-(
  • "我无法通过观察视图查看类成员变量。" — 我可以(VC++2010X)。
  • "我想只暴露接口部分(图中黄色类)以提高编译速度。"你不使用预编译的头文件吗?
  • 我应该尝试在 VS2010 上进行测试......和其他建议......谢谢。

标签: c++ inheritance multiple-inheritance virtual-functions


【解决方案1】:

鉴于上述描述,您应该无法实例化 CPet 的实例,因为纯虚函数 IAnimal::isAlive()IPet 虚表中未定义。

struct IAnimal {
    virtual ~IAnimal() {}
    virtual void isAlive() = 0;
};

struct IPet : public IAnimal {
};

struct CAnimal : public IAnimal {
    virtual void isAlive() {
    }
};

struct CPet : public CAnimal, public IPet {
};

int main(void) {
    CPet cp;
}

使用 Visual C++ 2008 和 2010 编译时生成以下内容:

animal.cpp(18) : error C2259: 'CPet' : cannot instantiate abstract class
    due to following members:
    'void IAnimal::isAlive(void)' : is abstract
    mytest.cpp(5) : see declaration of 'IAnimal::isAlive'

GCC 会产生类似的警告:

animal.cpp: In function 'int main()':
animal.cpp:18:7: error: cannot declare variable 'cp' to be of abstract type 'CPet'
animal.cpp:14:8: note:   because the following virtual functions are pure within 'CPet':
animal.cpp:3:15: note:  virtual void IAnimal::isAlive()

【讨论】:

  • 如果使用虚拟继承,一切正常。因此,DRH 的回答指出,需要虚拟继承才能使这种层次结构按预期工作。见,例如ideone.com/moCCp
  • 谢谢。正如 Managu 所说,“如果使用虚拟继承,一切正常”。但是我的编译器(Visual Studio 2008)说'警告 C4250:'CPet':通过支配继承 'CAnimal::CAnimal::isAlive'':(
  • 正确,您可以在此处阅读有关该警告(以及如何使其静音)的更多信息:msdn.microsoft.com/en-us/library/6b3sy7ae.aspx
猜你喜欢
  • 2017-02-07
  • 1970-01-01
  • 2012-01-20
  • 2015-12-23
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多