什么是多重重继承? [英] What is multiple re-inheritance?
问题描述
我将以下称为多重继承:
I refer to the following as "multiple re-inheritance":
- 直接继承一次类以及一次或多次间接继承其一个或多个后代
- 通过继承其两个或多个后代而间接继承一个类两次或更多次
我想知道它是否存在,以及如何明确地访问嵌入的子对象。
I want to know if it exists and how to unambiguously access embedded subobjects.
1。)[ ,2 nd ed。] †声明可编译程序不能有直接继承其直接父类和所述父类父类的类。是真的吗?
1.) [Professional C++, 2nd ed.]† states a compilable program can't have a class that directly inherits both its immediate parent and said parent's parent class. Is it true?
给予 GrandParent
和父
,它扩展 GrandParent
,VC12和g ++允许 GrandChild
直接继承两个 / code>和
GrandParent
。在VC12和g ++中,可以如下定义这些类:
Given a GrandParent
and Parent
, which extends GrandParent
, VC12 and g++ allows a GrandChild
to directly inherit from both Parent
and GrandParent
. In VC12 and g++, it’s possible to define these classes as follows:
GrandParent
声明一个 int num
数据成员。除了继承 GrandParent
',父声明自己的
num
s num
。 除了继承
Parent
',声明自己的
num
s和 GrandParent
的 num
s。
GrandParent
declares an int num
data member. Parent
declares its own num
in addition to inheriting GrandParent
's num
. GrandChild
declares its own num
in addition to inheriting Parent
's and GrandParent
's num
s.
似乎允许明确的成员访问全局,但g ++只允许在某些情况下。
VC12 seems to allow unambiguous member access across the board, but g++ only allows it for some cases.
#include <iostream>
using std::cout;
using std::endl;
struct GrandParent { int num; };
struct Parent : GrandParent { int num; };
struct GrandChild : GrandParent, Parent { int num; };
int main()
{
GrandChild gc;
gc.num = 2;
gc.Parent::num = 1;
gc.Parent::GrandParent::num = 0; // g++ error: ‘GrandParent’ is an ambiguous base of ‘GrandChild’
gc.GrandParent::num = 5; // g++ error: ‘GrandParent’ is an ambiguous base of ‘GrandChild’
// --VC12 output; g++ output--
cout << gc.num << endl; // 2 ; 2
cout << gc.Parent::num << endl; // 1 ; 1
cout << gc.Parent::GrandParent::num << endl; // 0 ; N/A due to above error
cout << gc.GrandParent::num << endl; // 5 ; N/A due to above error
}
code> gc.Parent :: GrandParent :: num 在g ++中不明确(b) gc.Parent :: num
? (a)唯一地描述其在继承树上的位置。 gc
只有1 Parent
子对象,只有1个 GrandParent
subobject,其中只有1 num
。对于(b), gc
有一个 Parent
,它具有自己的 num
,而且还有 GrandParent
子对象与另一个 num
。
2.) Why is (a) gc.Parent::GrandParent::num
ambiguous in g++ when (b) gc.Parent::num
isn't? (a) uniquely describes its location on the inheritance tree. gc
only has 1 Parent
subobject, which only has 1 GrandParent
subobject, which only has 1 num
. For (b), gc
has one Parent
, which has its own num
but also a GrandParent
subobject with another num
.
3。)对于 gc.GrandParent :: num
,似乎VC12看起来 gc
GrandParent
基本子对象用于后者的 num
。我猜它的原因是明确的,它是一个名称查找符合 gc
,所以实体在。
在 gc
的范围中查找,而最近的 GrandParent
到 gc
的范围是直接继承的,而不是通过 Parent
间接继承的范围。我错了?
3.) For gc.GrandParent::num
, it seems VC12 looks into gc
's immediate GrandParent
base subobject for the latter's num
. I’m guessing the reason it is unambiguous is that it’s a name lookup qualified by gc
, so the entity to the right of .
is looked for first in gc
's scope, and the most immediate GrandParent
to gc
's scope is the directly inherited one, not the indirectly inherited one via Parent
. Am I wrong?
4。)为什么 gc.GrandParent :: num
$ c> gc.Parent :: num 不是?如果一个是模糊的,那么不应该同样含糊吗?对于前者, gc
有两个 GrandParent
对于后者, Parent
有2 num
。
4.) Why is gc.GrandParent::num
ambiguous to g++ when gc.Parent::num
isn't? If one is ambiguous, then shouldn't both be equally ambiguous? For the prior, gc
has two GrandParent
s; and for the latter, Parent
has 2 num
s.
† Gregoire,Marc R. et al。 Professional C ++ ,2 nd ed。 Indianapolis,IN:Wiley Pubishing,2011。 241.打印。
†Gregoire, Marc R. et al. Professional C++, 2nd ed. Indianapolis, IN: Wiley Pubishing, 2011. p. 241. Print.
推荐答案
常见的术语是菱形图案 =https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem =nofollow>钻石问题)。
The common term for this is the diamond pattern (or diamond problem).
一个错误本身,但是如在这里的注释中所指出的,任何尝试访问在层次结构中的其他地方重复重复的直接基址将导致歧义错误。
It is not an error per se, but as noted in the comments here, any attempt to access a direct base that is reduplicated elsewhere in the hierarchy will result in an ambiguity error.
一个解决方法是使基地间接。 C ++ 11中的新继承构造函数允许完美的包装器:
One workaround would be to make the base indirect. The new inheriting constructors feature in C++11 allows perfect wrappers:
template< typename base, typename tag >
struct disambiguated_base : base
{ using base::base; };
给定一个未使用的标签类型,这将生成一个新类,派生自函数基础。标记类型可能是由精细化类型说明符表示的不完整类:
Given an unused tag type, this generates a new class derived from, and functionally identical to, the given base. The tag type may be an incomplete class denoted by an elaborated-type-specifier:
struct GrandChild : Parent,
disambiguated_base< GrandParent, class grandchild_grandparent_tag > {
typedef disambiguated_base< GrandParent, grandchild_grandparent_tag >
my_direct_grandparent;
int num;
};
现在 GrandChild
可以使用 my_direct_grandparent ::
以消除成员访问的歧义。
Now GrandChild
can use my_direct_grandparent::
to disambiguate member accesses.
这篇关于什么是多重重继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!