2009-10-16 3 views
7

Я не совсем понимаю:частное наследование

class Base 
{ 
    public: 
    Base() 
    { 
     cout<<"Base" << endl; 
    } 

    virtual void call() 
    { 
     cout<<"Base call" << endl; 
    } 
}; 

class Derived: private Base 
{ 
    public:  
    Derived() 
    { 
     cout<<"Derived" << endl; 
    } 
}; 

int main(void) 
{ 
    Base *bPtr = new Derived(); // This is not allowed 
} 

Это потому, что кто-то может позвонить по телефону() с помощью bPtr, который на самом деле делается на производный объект? Или есть другая причина?

ответ

18

Из общего понимания наследования, „частное наследование“ C++ это ужасно неправильно: это не наследования (насколько все за пределами класса обеспокоен), но полная деталь реализации класса.

Виден со стороны, частное наследство на самом деле почти такое же, как состав. Только внутри класса вы получаете специальный синтаксис, который больше напоминает наследование, чем состав.

Существует еще одно предупреждение: C++ синтаксически рассматривает это как наследование, со всеми вытекающими из этого преимуществами и проблемами, такими как scope visibility and accessibility. Кроме того, слепки C-типа (! Но не C++ не отбрасывать) фактически игнорирует видимость и, таким образом, удается Отдавая свой Derived указатель Base:

Base* bPtr = (Base*) new Derived(); 

Излишне говорить, что это зло .

+7

Это наследование реализации, а не наследование интерфейсов. –

+0

@ Лоуренс: правда, но это просто спорная терминология. Я был обеспокоен внешним видом класса. –

+1

«Это не наследование» «Абсолютно неправильно. Это ** является ** наследством, с частным доступом. – curiousguy

0

С личным наследованием вы теряете возможность обрабатывать свой производный объект как объект вашего базового класса.

1

Если вы наследуете конфиденциально, любой код, требующий преобразования из Derived * в Base *, должен быть членом или другом класса Derived.

+0

Спасибо за ответы, но я действительно хотел знать, почему они не позволили этому случиться. –

+0

@nitinsoman Потому что ** вы ** написали 'private'. Вот что такое частный доступ ... каков ваш вопрос? – curiousguy

9

Потому что private означает «деталь реализации», что делает факт, что Derived происходит от Base деталь реализации.

Частное наследование - это не наследование интерфейса, а наследование реализации. Он не выполняет отношения «Is-A», а «Is-Implemented-Using». Derived не является Base в отношении пользователей классов, это просто происходит (в настоящее время) с его использованием.

+0

Удивительное объяснение в таких небольших предложениях +1 – 2011-05-11 03:16:53

17

Открытое наследование означает, что все знают, что Derived является производным от базы.

Protected наследование означает, что только производный, друзья Производная и классы получены из Derived знают, что Derived является производным от базы. *

Частное наследование означает, что только производные и друзья Derived знают, что Derived является производным от базы ,

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

Частное наследование обычно используется для выполнения отношений «осуществляется в условиях». Одним из примеров может быть то, что Base предоставляет виртуальную функцию, которую вам нужно переопределить, и, следовательно, она должна быть унаследована, но вы не хотите, чтобы клиенты знали, что у вас есть эти отношения наследования.

* также: сколько было деревянного патрона ...

+4

Спустя три с половиной года и добавление к моему ответу: в случае частного наследования обратите внимание, что даже Base не знает, что Derived является производным от Base. То есть 'dynamic_cast (this)' в функции-члене базы всегда будет возвращать значение NULL, если Derived в частном порядке наследует от Base. Я упоминаю об этом, потому что он немного меня ударил, когда вы пытались наследовать частный класс класса, прошедшего через шаблон Curiously Recursive Template. –

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