我有一个抽象基类,它充当接口。来自两个派生类的多继承
我有两套派生类,它们实现了抽象类的一半。 (一个“set”定义了与初始化有关的抽象虚拟方法,另一个“set”定义了与实际“work”相关的那些)。然后我有派生类,它们使用多重继承来构造完全定义的类本身不添加任何东西)。
所以:(坏的伪代码)
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
似乎虚拟继承是这里的解决方案。我以前听说过虚拟继承,但是我没有把头绕在它周围。我仍然乐于接受建议。
这个结果不错,即使我非虚公共方法。但是,我将不得不尝试看看在将基类型指针用于派生类型的对象时会发生什么情况,以确保虚拟继承像虚函数重载一样工作:) – mmocny 2008-10-31 20:21:38
当从虚拟基类转换为派生类时,总是需要使用dynamic_cast <>,这又要求在虚拟基础中定义虚拟方法。虚拟基地的简单使用应该没有问题 - 它将以多态方式授予对派生类的访问权限。 – 2008-10-31 23:29:10