gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:53:41 28 4
gpt4 key购买 nike

我有一个作为接口(interface)的抽象基类。

我有两个“集”派生类,它们实现了抽象类的一半。 (一个“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;
}

因为,一个常见的习惯是让所有的虚拟方法都是私有(private)的。

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

无论如何,g++ 在尝试使用该类时提示:“对成员 init() 的请求不明确”。

我假设,如果我将 AbsBase 类用作纯接口(interface),则可以避免这种情况(假设上面的示例有效)。

所以:- 我的实现是否遥遥无期?- 这是将虚拟方法设为私有(private)的习语的限制吗?- 我如何重构我的代码来做我想做的事? (提供一个通用接口(interface),但允许一种方法将实现替换为“集合”成员函数)

编辑:

看来我不是第一个: http://en.wikipedia.org/wiki/Diamond_problem

似乎虚拟继承是这里的解决方案。我以前听说过虚拟继承,但我还没有深入了解它。我仍然愿意接受建议。

最佳答案

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


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

基本上,默认的非虚拟多重继承将在派生类中包含每个基类的拷贝,并包含它们的所有方法。这就是为什么您有两个 AbsBase 拷贝的原因——您的方法使用不明确的原因是两组方法都已加载,因此 C++ 无法知道要访问哪个拷贝!

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

关于c++ - 来自两个派生类的多重继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/254673/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com