gpt4 book ai didi

c++ - 什么是多重再继承?

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

我将以下称为“多重再继承”:

  • 直接继承一个类一次,通过继承其一个或多个后代来间接继承一个或多次
  • 通过继承一个类的两个或多个后代来间接继承一个类两次或多次

我想知道它是否存在以及如何明确地访问嵌入的子对象。

1.) [Professional C++, 2nd ed.] 指出可编译程序不能有直接继承的类它的直接父级和所述父级的父类。是真的吗?

给定一个 GrandParentParent , 扩展 GrandParent , VC12 和 g++ 允许 GrandChild直接从两个 Parent 继承和 GrandParent .在 VC12 和 g++ 中,可以这样定义这些类:

GrandParent声明 int num数据成员。 Parent声明自己的num除了继承GrandParentnum . GrandChild声明自己的num除了继承Parent的和 GrandParentnum秒。

VC12 似乎允许全面明确的成员访问,但 g++ 仅在某些情况下允许。

#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
}

2.) 为什么是 (a) gc.Parent::GrandParent::num当 (b) gc.Parent::num 在 g++ 中模棱两可不是吗? (a) 唯一地描述了它在继承树上的位置。 gc只有1个Parent子对象,只有 1 个 GrandParent子对象,只有 1 个 num .对于 (b),gc有一个Parent , 它有自己的 num还有一个GrandParent与另一个 num 的子对象.

3.) 对于 gc.GrandParent::num ,似乎 VC12 正在查看 gc的即时GrandParent后者的 num 的基础子对象.我猜它是明确的原因是它是由 gc 限定的名称查找。 , 所以 . 右边的实体在 gc 中首先查找的范围,最直接的 GrandParentgc的作用域是直接继承的,不是通过Parent间接继承的.我错了吗?

4.) 为什么是 gc.GrandParent::numgc.Parent::num 时对 g++ 模棱两可不是吗?如果一个是模棱两可的,那么两者不应该同样模棱两可吗?对于之前,gc有两个 GrandParent小号;对于后者,Parent有 2 num秒。


Gregoire、Marc R. 等人。 专业 C++,第 2nd 版。印第安纳波利斯:威利出版社,2011 年。 241. 打印。

最佳答案

对此的常用术语是菱形图案(或diamond problem)。

这本身并不是一个错误,但正如这里的评论中所指出的,任何尝试访问在层次结构中其他地方重复的直接基础都将导致歧义错误。

一种解决方法是使基础间接。 C++11 中新的继承构造函数特性允许完美的包装器:

template< typename base, typename tag >
struct disambiguated_base : base
{ using base::base; };

给定一个未使用的标签类型,这会生成一个新类,该类派生自给定的基类,并且在功能上与给定的基类相同。标记类型可能是由详细类型说明符表示的不完整类:

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:: 来消除成员访问的歧义。

关于c++ - 什么是多重再继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20693848/

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