C++ 具有多重继承的模糊基础
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7197887/
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
Ambiguous base with multiple inheritance
提问by David Doria
I am trying to write some subclasses of classes in a big library. I am getting an "ambiguous base" error. Here is a compilable example of the problem:
我正在尝试在一个大库中编写一些类的子类。我收到“不明确的基础”错误。这是该问题的可编译示例:
#include <iostream>
// I can't change these because they are in the library:
class InteractorStyle {};
class InteractorStyleCamera : public InteractorStyle {};
class InteractorStyleImage : public InteractorStyle {};
// These are my subclasses (so I can change them):
class PointSelector : public InteractorStyle {};
class PointSelector2D : public InteractorStyleCamera, public PointSelector
{
// This function has to exist exactly like this (a requirement of the library):
static PointSelector2D* SafeDownCast(InteractorStyle *o)
{
return static_cast<PointSelector2D *>(o);
}
};
int main()
{
return 0;
}
The error is
错误是
error: ‘InteractorStyle' is an ambiguous base of ‘PointSelector2D'.
错误:“InteractorStyle”是“PointSelector2D”的不明确基础。
Is there anything I can do in this case?
在这种情况下我能做些什么吗?
采纳答案by John Humphreys - w00te
Your problem is that Interactor style is inherited twice - once by PointSelector2D and once by InteractorStyleCamera. This means that you have 2 versions of every member of it contained within your class.
您的问题是交互器样式继承了两次 - 一次由 PointSelector2D 继承,一次由 InteractorStyleCamera 继承。这意味着您的类中包含它的每个成员的 2 个版本。
Check out:
查看:
How can I avoid the Diamond of Death when using multiple inheritance?
And try virtual inheritance.
并尝试虚拟继承。
回答by AnT
You can superficially "fix" it by using a two-step cast. For example
您可以使用两步演员表从表面上“修复”它。例如
static_cast<PointSelector2D *>(static_cast<InteractorStyleCamera *>(o));
Of course, you have to keep in mind that this "fixes" the syntax, but doesn't fix the underlying structural problem. Your PointSelector2D
has two InteractorStyle
base subobjects inside. Depending from which InteractorStyle
base subobjects you start, the upcast path is different. And it is very important to take the correct path. What I wrote above is for InteractorStyle
inside InteractorStyleCamera
. For the other base the proper upcast would be
当然,您必须记住,这“修复”了语法,但并没有修复潜在的结构问题。你里面PointSelector2D
有两个InteractorStyle
基础子对象。根据您从哪个InteractorStyle
基础子对象开始,向上转换的路径是不同的。走正确的道路非常重要。我上面写的是InteractorStyle
inside InteractorStyleCamera
。对于另一个基地,正确的 upcast 将是
static_cast<PointSelector2D *>(static_cast<PointSelector *>(o));
If you are just given an InteractorStyle *
pointer with no extra information about which base it is pointing to, then you can't possibly solve your problem with static_cast
. There's no way to know which upcast path to take. Taking the wrong one will produce a totally meaningless result.
如果你只是得到一个InteractorStyle *
指针而没有关于它指向哪个基的额外信息,那么你不可能用static_cast
. 没有办法知道要采取哪条上行路径。选择错误的将产生完全没有意义的结果。
As it has been noted already, dynamic_cast
can help in this situation, but it has additional requirements (polymorphic starting type). Your types are not polymorphic (at least in your quoted example), so dynamic_cast
will not accept them for upcasts.
正如已经指出的,dynamic_cast
在这种情况下可以提供帮助,但它有额外的要求(多态起始类型)。您的类型不是多态的(至少在您引用的示例中),因此dynamic_cast
不会接受它们进行向上转换。
回答by templatetypedef
I believe you can fix this by using a dynamic_cast
instead of a static_cast
. The dynamic_cast
can look at the object at runtime to determine which of the two InteractorStyle
base classes is being pointed at, and from there can adjust the pointer down to the appropriate type.
我相信你可以通过使用 adynamic_cast
而不是 a来解决这个问题static_cast
。在dynamic_cast
可以看一下对对象在运行时确定两个的InteractorStyle
基类被指向,并从那里可以调整指针下降到合适的类型。
回答by Seth Carnegie
You can get your code to compile (I got your example to compile at least) by adding InteractorStyle
to the classes that PointSelector2D
inherits from. Whether this is a long term solution is not known by me.
您可以通过添加InteractorStyle
到PointSelector2D
继承自的类来编译代码(我至少让您的示例编译)。我不知道这是否是一个长期解决方案。