C++ 来自两个派生类的多重继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/254673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple Inheritance from two derived classes
提问by mmocny
I have an abstract base class which acts as an interface.
我有一个抽象基类,它充当接口。
I have two "sets" of derived classes, which implement half of the abstract class. ( one "set" defines the abstract virtual methods related to initialization, the other "set" defines those related to the actual "work". )
我有两个派生类的“集合”,它们实现了抽象类的一半。(一个“集合”定义了与初始化相关的抽象虚拟方法,另一个“集合”定义了与实际“工作”相关的那些。)
I then have derived classes which use multiple inheritance to construct fully defined classes ( and does not add anything itself ).
然后我有派生类,它们使用多重继承来构造完全定义的类(并且本身不添加任何内容)。
So: ( bad pseudocode )
所以:(错误的伪代码)
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
}
First of all, can I do this? Can I inherit from two classes which are both derived from the same Base? (I hope so).
首先,我可以这样做吗?我可以从两个派生自同一个 Base 的类继承吗?(但愿如此)。
Here is the "real problem", though (I lied a bit above to simplify the example).
不过,这是“真正的问题”(为了简化示例,我在上面撒了一点谎)。
What I have really gone and done is add non abstract accessors methods to the base class:
我真正所做的是向基类添加非抽象访问器方法:
class AbsBase {
public:
void init() { init_impl(); }
void work() { work_impl(); }
private:
virtual void init_impl() = 0;
virtual void work_impl() = 0;
}
Because, a common idiom is to make all virtual methods private.
因为,一个常见的习惯用法是将所有虚拟方法设为私有。
Unfortunately, now both AbsInit, and AbsWork inherit these methods, and so NotAbsTotal inherits "two of each" ( I realize I may be butchering what is really happening at compile time ).
不幸的是,现在 AbsInit 和 AbsWork 都继承了这些方法,因此 NotAbsTotal 继承了“每个两个”(我意识到我可能正在扼杀编译时真正发生的事情)。
Anyway, g++ complains that: "request for member init() is ambiguous" when trying to use the class.
无论如何,g++ 抱怨说:在尝试使用该类时“对成员 init() 的请求不明确”。
I assume that, had I used my AbsBase class as a pure interface, this would have been avoided ( assuming that the top example is valid ).
我假设,如果我使用我的 AbsBase 类作为纯接口,这将被避免(假设最上面的例子是有效的)。
So: - Am I way off with my implementation? - Is this a limitation of the idiom of making virtual methods private? - How do I refactor my code to do what I want? ( Provide one common interface, but allow a way to swap out implementations for "sets" of member functions )
所以: - 我的实现是否离我很远?- 这是将虚拟方法设为私有的习惯用法的限制吗?- 我如何重构我的代码来做我想做的事?(提供一个通用接口,但允许一种方法来交换成员函数“集合”的实现)
Edit:
编辑:
Seems I am not the first one: http://en.wikipedia.org/wiki/Diamond_problem
似乎我不是第一个:http: //en.wikipedia.org/wiki/Diamond_problem
Seems Virtual Inheritance is the solution here. I have heard of virtual inheritance before, but I have not wrapped my head around it. I am still open to suggestions.
似乎虚拟继承是这里的解决方案。我以前听说过虚拟继承,但我并没有深入了解它。我仍然愿意接受建议。
回答by comingstorm
It looks like you want to do virtual inheritance. Whether that turns out to actually be a good idea is another question, but here's how you do it:
看起来你想做虚拟继承。这是否真的是一个好主意是另一个问题,但这是你如何做到的:
class AbsBase {...};
class AbsInit: public virtual AbsBase {...};
class AbsWork: public virtual AbsBase {...};
class NotAbsTotal: public AbsInit, public AbsWork {...};
Basically, the default, non-virtual multiple inheritance will include a copy of each base classin the derived class, and includes all their methods. This is why you have two copies of AbsBase -- and the reason your method use is ambiguous is both sets of methods are loaded, so C++ has no way to know which copy to access!
基本上,默认的非虚拟多重继承将包括派生类中每个基类的副本,并包括它们的所有方法。这就是为什么你有两个 AbsBase 副本——你的方法使用不明确的原因是两组方法都被加载,所以 C++ 无法知道要访问哪个副本!
Virtual inheritance condenses all references to a virtual base class into one datastructure. This should make the methods from the base class unambiguous again. However, note: if there is additional data in the two intermediate classes, there may be some small additional runtime overhead, to enable the code to find the shared virtual base class.
虚拟继承将所有对虚拟基类的引用压缩到一个数据结构中。这应该使基类中的方法再次明确。但是,注意:如果两个中间类中有额外的数据,可能会有一些小的额外运行时开销,以使代码能够找到共享的虚拟基类。
回答by James Curran
It can be done, although it gives most the shivers.
这是可以做到的,尽管它让大多数人不寒而栗。
You need to use "virtual inheritance", the syntax for which is something like
您需要使用“虚拟继承”,其语法类似于
class AbsInit: public virtual AbsBase {...};
class AbsWork: public virtual AbsBase {...};
class NotAbsTotal: public AbsInit, public AbsWork {...};
Then you have to specify which function you want to use:
然后,您必须指定要使用的函数:
NotAbsTotal::work()
{
AbsInit::work_impl();
}
(UPDATED with correct syntax)
(使用正确的语法更新)
回答by Martin v. L?wis
You need to to declare the inheritance as virtual:
您需要将继承声明为虚拟:
struct AbsBase {
virtual void init() = 0;
virtual void work() = 0;
};
struct AbsInit : virtual public AbsBase {
void init() { }
};
struct AbsWork : virtual public AbsBase {
void work() { }
};
struct NotAbsTotal : virtual public AbsInit, virtual public AbsWork {
};
void f(NotAbsTotal *p)
{
p->init();
}
NotAbsTotal x;
回答by Rob Wells
You have to start thinking in the terms of what you are trying to model here.
您必须开始考虑您要在这里建模的内容。
Public inheritance should only ever be used to model an "isa" relationship, e.g. a dog is a animal, a square is a shape, etc.
公共继承应该只用于模拟“isa”关系,例如狗是动物,正方形是形状等。
Have a look at Scott Meyer's book Effective C++ for an excellent essay on what the various aspects of OO design should only ever be interpreted as.
看看 Scott Meyer 的《Effective C++》一书,这是一篇关于 OO 设计的各个方面应该被解释为什么的优秀文章。
Edit: I forgot to say that while the answers so far provided are technically correct I don't think any of them address the issues of what you are trying to model and that is the crux of your problem!
编辑:我忘了说,虽然到目前为止提供的答案在技术上是正确的,但我认为它们中的任何一个都没有解决您要建模的问题,而这正是您问题的症结所在!
HTH
HTH
cheers,
干杯,
Rob
抢
回答by Techman92
I found a good and simple example at the below link. The article explains with an example program for calculating the area and perimeter of a rectangle. You can check it..cheers
我在下面的链接中找到了一个很好的简单示例。文章通过一个示例程序来说明计算矩形的面积和周长。你可以检查一下..干杯
Multilevel Inheritance is an inheritance hierarchy wherein one derived class inherits from multiple Base Classes. Read more..
多级继承是一种继承层次结构,其中一个派生类从多个基类继承。阅读更多..
http://www.mobihackman.in/2013/09/multiple-inheritance-example.html
http://www.mobihackman.in/2013/09/multiple-inheritance-example.html