我有一个充当接口的抽象基类。
我有两个“集”派生类,它们实现了抽象类的一半。(一个“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
似乎虚拟继承是这里的解决方案。我以前听说过虚拟继承,但我还没有深入了解它。我仍然愿意接受建议。