Программирование >>  Инициализация объектов класса, структура 

1 ... 316 317 318 [ 319 ] 320 321 322 ... 395


extern void dance( const Bear* ); extern void rummage( const Raccoon* );

extern ostreamS

operator ( ostreamS, const ZooAAnimalS );

int main() {

Panda yin yang;

dance( Syin yang ); правильно rummage( &yin yang ); правильно cout << yin yang; правильно

...

виртуальное наследование:

Любой класс, который можно задать в качестве базового, разрешается сделать виртуальным, причем он способен содержать все те же элементы, что обычные базовые

#include <iostream> #include <string>

class ZooAnimal; extern ostreamS

operator ( ostreamS, const ZooAAnimalS ); class ZooAnimal {

public:

ZooAnimal( string name,

bool onExhibit, string fam name ) : name ( name ),

onExhibit( onExhibit ), fam name( fam name ) {}

virtual ~ZooAAnimal() ;

virtual ostreamS print( ostreamS ) const; string name() const { return name; } string family name() const { return fam name; }

...

protected:

bool onExhibit; string name; string fam name;

...

классы. Так выглядит объявление ZooAnimial: };

К объявлению и реализации непосредственного базового класса при использовании виртуального наследования добавляется ключевое слово virtual. Вот, например, объявление нашего класса Bear:

преобразования базовых классов Panda выполняются корректно, хотя Panda использует



class Bear : public virtual ZooAnimal { public:

enum DanceType {

two left feet, macarena, fandango, waltz };

Bear

( string name, bool onExhibit=true ) : ZooA\nimal( name, onExhibit, Bear ), dance( two left feet ) {}

virtual ostream& print( с void dance( DanceType );

ostream& ) const;

void dance(

protected:

DanceType dance;

...

class Raccoon : public virtual ZooAnimal {

public:

Raccoon( string name, bool onExhibit=true )

: ZooAnimal( name, onExhibit, Raccoon ), pettable( false )

virtual ostream& print( ostream& ) const;

bool pettable() const { return pettable; } void pettable( bool petval ) { pettable = petval; }

...

protected:

bool pettable;

...

А вот объявление класса Raccoon:

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

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



class Panda : public Bear,

public Raccoon,

public Endangered { public:

Panda( string name, bool onExhibit=true ); virtual ostreamS print( ostreamS ) 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. Когда мы пишем:

cout << meeko.family name();



1 ... 316 317 318 [ 319 ] 320 321 322 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика