С++ для начинающих



     film noir Movies - YouTube. | Малахит на http://www.redkiekamni.ru. |     

Специальная семантика инициализации


Наследование, в котором присутствует один или несколько виртуальных базовых классов, требует специальной семантики инициализации. Взгляните еще раз на реализации Bear и Raccoon в предыдущем разделе. Видите ли вы, какая проблема связана с порождением класса Panda?

class Panda : public Bear,

              public Raccoon, public Endangered {

public:

      Panda( string name, bool onExhibit=true );

      virtual ostream& print( ostream& ) const;

      bool sleeping() const { return _sleeping; }

      void sleeping( bool newval ) { _sleeping = newval; }

      // ...

protected:

      bool _sleeping;

      // ...

};

Проблема в том, что конструкторы базовых классов Bear и Raccoon вызывают конструктор ZooAnimal с неявным набором аргументов. Хуже того, в нашем примере значения по умолчанию для аргумента fam_name (название семейства) не только отличаются, они еще и неверны для Panda.

В случае невиртуального наследования производный класс способен явно инициализировать только свои непосредственные базовые классы (см. раздел 17.4). Так, классу Panda, наследующему от ZooAnimal, не разрешается напрямую вызвать конструктор ZooAnimal в своем списке инициализации членов. Однако при виртуальном наследовании только Panda может напрямую вызывать конструктор своего виртуального базового класса ZooAnimal.

Ответственность за инициализацию виртуального базового возлагается на ближайший производный класс. Например, когда объявляется объект класса Bear:

Bear winnie( "pooh" );

то Bear является ближайшим производным классом для объекта winnie, поэтому выполняется вызов конструктора ZooAnimal, определенный в классе Bear. Когда мы пишем:

cout << winnie.family_name();

будет выведена строка:

The family name for pooh is Bear

(Название семейства для pooh – это Bear)

Аналогично для объявления

Raccoon meeko( "meeko" );

Raccoon – это ближайший производный класс для объекта meeko, поэтому выполняется вызов конструктора ZooAnimal, определенный в классе Raccoon. Когда мы пишем:




Содержание  Назад  Вперед