2016-06-25 6 views
2

Как работает следующий код? Конструктор MakeFinal защищен, поэтому он не должен быть доступен для класса FinalUser. Но я не получил никаких ошибок сборки или выполнения.Защищенный конструктор в многоуровневом виртуальном наследовании в C++

class MakeFinal 
{ 
protected: 
    MakeFinal(void) {}; 

public: 
    ~MakeFinal(void) {}; 
}; 

class Final : virtual public MakeFinal 
{ 
public: 
    Final(void) {}; 
    ~Final(void) {}; 
}; 

class FinalUser : public Final 
{ 
public: 
    FinalUser(void) {}; 
    ~FinalUser(void) {}; 
}; 

int main() 
{ 
    FinalUser *finalUserHeap_ = new FinalUser(); 
    return 0; 
} 
+0

'FinalUser' не требует прямого доступа к' MakeFinal'. –

ответ

0

Производные классы имеют доступ к защищенным членам их базовых классов. В этом разница между protected и private.

1

Вы должны знать следующее:

Если наследование public, все, что известно о Base и ребенка также известно, что ребенок наследует от базы.

Если наследование равно protected, то только Child и его дети знают, что они наследуют от Base.

Если наследование равно private, никто, кроме ребенка, не знает о наследовании.

@Anzurio ответ в Difference between private, public, and protected inheritance

Согласно этим. Вы должны использовать private, если вы хотите, чтобы у FinalUser класса donot есть доступ к MakeFinal.

1

A virtual базовый класс инициализируется списком инициализаторов элементов самого производного класса.

Поскольку база virtual может быть обычным объектом базового класса для нескольких производных классов, и инициализации, указанные этими производными классами, могут конфликтовать.

Спецификация инициализации в наиболее производном классе действует, как если бы концептуально наиболее производный класс был получен непосредственно из virtual базового класса, т.е.

FinalUser(void) {}; 

& hellip; эквивалентно

FinalUser(): MakeFinal() {} 

Поскольку MakeFinal конструктор protected, он доступен для всех производных классов.

Это относится к классу FinalUser.


В других новостях:

Имена в этом коде указывают, что это об использовании C++ 03 трюк с создания класса, который не может быть (полезно), полученный из, “ ” окончательное класс. Трюк состоит в том, чтобы иметь шаблон шаблона, который может действовать как самый производный класс, и который имеет необходимый friend -hip для доступа к другим классам недоступного конструктора базового класса virtual. В C++ 11 было введено ключевое слово final, чтобы сделать это проще и без накладных расходов наследования virtual.

+0

Очень полный ответ. – chema989

+0

Спасибо - я добавил одну защищенную функцию foo() в класс MakeFinal и попытался получить доступ к ней через * finalUserHeap_, но компилятор говорит, что foo() недоступен finalUserHeap_. Означает ли это, что вы объяснили только для конструкторов? – Ravi

+0

@Ravi: он доступен в классе 'FinalUser', как и конструктор, но только для вызовов объекта известного типа' FinalUser' или производного. Я бы предположил, что ваш тестовый код назвал его на объект известного типа 'Final' или' MakeFinal'. Это ограничение на 'protected' - это легкая защита от случая непреднамеренного получения базового класса и доступа к защищенным частям класса sibling. –

 Смежные вопросы

  • Нет связанных вопросов^_^