Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
class InvalidArgumentException : public Exception
{
public :
InvalidArgumentException( int arg , char*pFile , int nLine )
: Exception( "Некорректный аргумент" , pFile , nLine )
{
invArg = arg ;
}
virtual void display( ostream & out )
{
Exception::display( out ) ;
out << "Аргумент " << invArg << endl ;
}
protected :
int invArg ;
}
Вызывающая функция автоматически обработает новое исключение, поскольку InvalidArgumentException ЯВЛЯЕТСЯ Exception , а функция-член display( ) — полиморфна.
_________________
297 стр. Глава 25. Обработка ошибок и исключения
ОГЛАВЛЕНИЕ
В этой главе...
►Механизм множественного наследования 298
►Устранение неоднозначностей множественного наследования 300
►Виртуальное наследование 301
►Конструирование объектов 306
►Отрицательные стороны множественного наследования 306
В иерархиях классов, которые рассматривались в этой книге, каждый класс наследовался от одного прародителя. Такое одиночное наследование подходит для описания большинства объектов реального мира. Однако некоторые классы представляют собой сочетание нескольких классов в одном.
Примером такого класса может служить диван-кровать. Как видно из названия, это и диван, и кровать ( правда, кровать не очень удобная ). Таким образом, этот предмет интерьера наследует свойства как дивана, так и кровати. В терминалах С++ эту ситуацию можно описать следующим образом: класс может быть наследником более чем одного базового класса. Такое наследование называется множественным.
►Механизм, множественного наследования...298
Чтобы увидеть множественное наследование в действии, я продолжу пример с диваном-кроватью. На рис. 26.1 приведена схема наследования дивана-кровати ( класс SleeperSofa ). Обратите внимание, что этот класс наследует свойства и от класса Bed ( Кровать ), и от класса Sofa ( Диван ), т.е. наследует свойства обоих классов.
Рис. 26.1. Иерархия классов дивана-кровати
_________________
298 стр. Часть 5. Полезные особенности
Программная реализация класса SleeperSofa выглядит следующим образом.
//
/* MultipleInheritance — класс, являющийся наследником */
/* нескольких базовых классов */
//
#include
#include
#include
using namespace std ;
class Bed
{
public :
Bed( ) { }
void sleep( ) { cout << "Спим" << endl ; }
int weight ;
} ;
class Sofa
{
public :
Sofa( ) { }
void watchTV( ) { cout << "Смотрим телевизор" << endl ; }
int weight ;
} ;
/* SleeperSofa — диван-кровать */
class SleeperSofa : public Bed , public Sofa
{
public :
SleeperSofa( ) { }
void foldOut( ) { cout << "Раскладываем диван-кровать"
<< endl ; }
} ;
int main( int nNumberofArgs , char* pszArgs[ ] )
{
/* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */
setlocale ( LC_ALL , ".1251" ) ;
SleeperSofa ss ;
/* Посмотрим телевизор на диване... */
ss.watchTV( ) ; /* Sofa::watchTV( ) */
/* ...разложим его в кровать... */
ss.foldOut( ) ; /* SleeperSofa::foldOut( ) */
/* ...и ляжем спать */
ss.sleep( ) ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
В этом примере класс SleeperSofa наследует оба класса — Bed и Sofa . Это видно из их наличия в объявлении класса SleeperSofa , который наследует все члены от обоих базовых классов. Таким образом, допустимы оба вызова — как ss.sleep( ) , так и ss.watchTV( ) . Вы можете использовать SleeperSofa и как Bed , и как Sofa . Кроме того, класс SleeperSofa имеет собственные члены, например foldOut( ) . В результате мы получим следующий вывод программы:
Смотрим телевизор
Раскладываем диван-кровать
Спим
Press any key to continue...
_________________
299 стр. Глава 26. Множественное наследование
►Устранение неоднозначностей множественного наследования...300
Будучи весьма мощной возможностью языка, множественное наследование может стать в то же время и источником проблем. Одну из них можно увидеть уже в предыдущем примере. Обратите внимание, что оба класса — Bed и Sofa — содержат член weight ( вес ). Это логично, потому что они оба имеют некоторый вполне измеримый вес. Вопрос: какой именно член weight наследует класс SleeperSofa ?
Ответ прост: оба. Класс SleeperSofa наследует отдельный член Bed::weight и отдельный член Sofa::weight . Поскольку они оба имеют одно и то же имя, обращения к weight теперь являются двузначными, если только не указывать явно, к какому именно weight мы намерены обратиться. Это демонстрирует следующий фрагмент кода:
#include
void fn( )
{
SleeperSofa ss ;
cout << "Beс = "
<< ss.weight /* неправильно — какой именно вес? */
<< "\n" ;
}
Теперь в программе нужно явно указывать, какая именно переменная weight нужна, используя для этого имя базового класса. Приведённый ниже пример вполне корректен.
#include
void fn( )
{
SleeperSofa ss ;
cout << "Вес дивана = "
<< ss.Sofa::weight /*укажем, какой именно вес */
<< "\n" ;
}
Хотя такое решение и устраняет ошибку, указание имени базового класса во внешнем приложении нежелательно: ведь при этом информация о внутреннем устройстве класса должна присутствовать за его пределами. В нашем примере функция fn( ) должна располагать сведениями о том, что класс SleeperSofa наследуется от класса Sofa . Такие конфликты имён невозможны при одиночном наследовании, но служат постоянным источником неприятностей при наследовании множественном.
_________________
300 стр. Часть 5. Полезные особенности
►Виртуальное наследование...301
В случае класса SleeperSofa конфликт имён weight является, по сути, небольшим недоразумением. Ведь на самом деле диван-кровать не имеет отдельного веса как кровать, и отдельного веса как диван. Конфликт возник потому, что такая иерархия классов не вполне адекватно описывает реальный мир. Дело в том, что разложение на классы оказалось неполным.
Если немного подумать над этой проблемой, становится ясно, что и кровать и диван являются частными случаями некоторой более фундаментальной концепции мебели ( думаю, можно было предложить нечто ещё более фундаментальное, но для нас достаточно ограничиться мебелью ). Вес является свойством любой мебели, что показано на рис. 26.2.
Читать дальшеИнтервал:
Закладка: