Я называю следующее "множественное повторное наследование":
- наследование класса один раз прямо и один или несколько раз косвенно путем наследования одного или нескольких его потомков
- наследуя класс косвенно два или более раза, наследуя двух или более своих потомков
Я хочу знать, существует ли он и как однозначно обращаться к встроенным подобъектам.
1.) [Professional С++, 2 nd ed.] † указывает, что компилируемая программа не может иметь класс, который непосредственно наследует как своего непосредственного родителя, так и указанного родителя родительский класс. Это правда?
Учитывая GrandParent
и Parent
, который расширяет GrandParent
, VC12 и g++ позволяют GrandChild
напрямую наследовать как от Parent
, так и от GrandParent
. В VC12 и g++ его можно определить следующим образом:
GrandParent
объявляет элемент данных int num
. Parent
объявляет свой собственный num
в дополнение к наследованию GrandParent
num
. GrandChild
объявляет свой собственный num
в дополнение к наследованию Parent
и GrandParent
num
s.
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
неоднозначно в g++, когда (b) gc.Parent::num
нет? (а) однозначно описывает свое местоположение в дереве наследования. gc
имеет только один подобъект 1 Parent
, у которого есть только один GrandParent
подобъект, который имеет только 1 num
. Для (b) gc
имеет один Parent
, который имеет свой собственный num
, но также подобъект GrandParent
с другим num
.
3.) Для gc.GrandParent::num
кажется, что VC12 смотрит в базовый подобъект gc
непосредственного GrandParent
для последнего num
. Я предполагаю, что он однозначен в том, что его поиск по имени определяется gc
, поэтому сущность справа от .
просматривается сначала в области gc
, а самая непосредственная GrandParent
- gc
scope является непосредственно унаследованным, а не косвенно унаследованным через Parent
. Я не прав?
4.) Почему gc.GrandParent::num
неоднозначно относится к g++, когда gc.Parent::num
нет? Если человек неоднозначен, то не должны ли быть одинаково двусмысленными? Для предыдущего gc
имеет два GrandParent
s; и для последнего Parent
имеет 2 num
s.
† Грегуар, Марк Р. и др. Professional С++, 2 nd ed. Индианаполис, IN: Wiley Pubishing, 2011. p. 241. Печать.