Я называю следующее "множественное повторное наследование":
- наследование класса один раз прямо и один или несколько раз косвенно путем наследования одного или нескольких его потомков
- наследуя класс косвенно два или более раза, наследуя двух или более своих потомков
Я хочу знать, существует ли он и как однозначно обращаться к встроенным подобъектам.
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. Печать.