什么是多重重继承? [英] What is multiple re-inheritance?

查看:190
本文介绍了什么是多重重继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将以下称为多重继承:

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 nums.

似乎允许明确的成员访问全局,但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 GrandParents; and for the latter, Parent has 2 nums.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆