我有一个充当接口的抽象基类。
我有两个“集合”派生类,它们实现了抽象类的一半。(一个“集合”定义与初始化相关的抽象虚拟方法,另一个“集合”定义与实际工作相关的方法。)
然后我有派生类,使用多重继承构建完全定义的类(并且本身不添加任何内容)。
因此:(错误的伪代码)
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
}
首先,我能这样做吗?我可以从两个都派生自同一基类的类中继承吗?(希望可以)。
不过这里有一个“真正的问题”(我在上面说了谎以简化示例)。
我实际上添加了非抽象访问器方法到基类:
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 ++会报告:“request for member init() is ambiguous”。
我认为,如果我将我的AbsBase类用作纯接口,则可以避免这种情况(假设顶部示例有效)。
所以: - 我的实现是否完全错误? - 将虚方法设置为私有的惯用语是否存在限制? - 如何重构我的代码以实现我的目标?(提供一个公共接口,但允许一种方式来交换“一组”成员函数的实现)
编辑:
看起来我不是第一个遇到这个问题的人: http://en.wikipedia.org/wiki/Diamond_problem
似乎虚继承是这里的解决方案。我之前听说过虚继承,但还没理解透彻。我仍然愿意听取建议。