当前位置:  开发笔记 > 编程语言 > 正文

来自两个派生类的多重继承

如何解决《来自两个派生类的多重继承》经验,为你挑选了1个好方法。

我有一个抽象的基类作为接口.

我有两个派生类的"集合",它们实现了抽象类的一半.(一个"set"定义与初始化相关的抽象虚拟方法,另一个"set"定义与实际"工作"相关的那些.)

然后,我得到了使用多继承来构造完全定义的类的派生类(并且本身不添加任何东西).

所以:(坏伪代码)

class AbsBase {
  virtual void init() = 0;
  virtual void work() = 0;
}

class AbsInit : public AbsBase {
  void init() { do_this(); }
  // work() still abs
}

class AbsWork : public AbsBase {
  void work() { do_this(); }
  // init() still abs
}

class NotAbsTotal : public AbsInit, public AbsWork {
  // Nothing, both should be defined
}

首先,我可以这样做吗?我可以继承两个派生自同一Base的类吗?(希望如此).

虽然这是"真正的问题"(我在上面撒谎以简化示例).

我真正做的是将非抽象访问器方法添加到基类:

class AbsBase {
public:
  void init() { init_impl(); }
  void work() { work_impl(); }

private:
  virtual void init_impl() = 0;
  virtual void work_impl() = 0;
}

因为,一个常见的习惯用法是将所有虚拟方法设为私有.

不幸的是,现在AbsInit和AbsWork都继承了这些方法,因此NotAbsTotal继承了"两个"(我意识到我可能正在屠杀编译时真正发生的事情).

无论如何,g ++抱怨说:"当尝试使用该类时,"成员init()的请求是不明确的.

我假设,如果我使用我的AbsBase类作为纯接口,这将被避免(假设顶部示例有效).

那么: - 我的实施方式是否可行? - 这是将虚拟方法设为私有的习惯用法的限制吗? - 我如何重构我的代码来做我想要的?(提供一个通用接口,但允许一种方法来替换成员函数"集合"的实现)

编辑:

似乎我不是第一个:http: //en.wikipedia.org/wiki/Diamond_problem

似乎虚拟继承是这里的解决方案.我之前听说过虚拟继承,但我没有把头包裹起来.我仍然愿意接受建议.



1> comingstorm..:

看起来你想要做虚拟继承.这是否真的是一个好主意是另一个问题,但这是你如何做到这一点:

class AbsBase {...};
class AbsInit: public virtual AbsBase {...};
class AbsWork: public virtual AbsBase {...};
class NotAbsTotal: public AbsInit, public AbsWork {...};

基本上,默认的非虚拟多重继承将包括派生类中每个基类的副本,并包括它们的所有方法.这就是为什么你有两个AbsBase副本 - 并且你的方法使用不明确的原因是加载了两组方法,所以C++无法知道要访问哪个副本!

虚拟继承将对虚拟基类的所有引用压缩为一个数据结构.这应该使基类中的方法再次明确.但是,请注意:如果两个中间类中有其他数据,则可能会有一些额外的运行时开销,以使代码能够找到共享的虚拟基类.

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有