Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Синтезируемый оператор присвоения копии ведет себя так же, как и конструктор копий. Сначала он присваивает часть Bear
(и его часть ZooAnimal
) объекта, затем часть Endangered
и наконец часть Panda
. Оператор присвоения при перемещении ведет себя подобным образом.
Упражнение 18.21. Объясните следующие объявления. Найдите все ошибки и объясните их причину:
(a) class CADVehicle : public CAD, Vehicle { ... };
(b) class DblList: public List, public List { ... };
(c) class iostream: public istream, public ostream { ... };
Упражнение 18.22. С учетом следующей иерархии класса, в которой у каждого класса определен стандартный конструктор:
class A { ... };
class B : public A { ... };
class C : public B { ... };
class X { ... };
class Y { ... };
class Z : public X, public Y { ... };
class MI : public C, public Z { ... };
Каков порядок выполнения конструкторов при создании следующего объекта?
MI mi;
18.3.2. Преобразования и несколько базовых классов
При одиночном наследовании указатель или ссылка на производный класс могут быть автоматически преобразованы в указатель или ссылку на базовый класс (см. раздел 15.2.2 и раздел 15.5). Это справедливо и для множественного наследования. Указатель или ссылка на производный класс могут быть преобразованы в указатель или ссылку на любой из его базовых классов. Например, указатель или ссылка на класс ZooAnimal
, Bear
или Endangered
может указывать или ссылаться на объект класса Panda
.
// функции, получающие ссылки на класс, базовый для класса Panda
void print(const Bear&);
void highlight(const Endangered&);
ostream& operator<<(ostream&, const ZooAnimal&);
Panda ying_yang("ying_yang");
print(ying_yang); // передает объект класса Panda как
// ссылку на объект класса Bear
highlight(ying_yang); // передает объект класса Panda как
// ссылку на объект класса Endangered
cout << ying_yang << endl; // передает объект класса Panda как
// ссылку на объект класса ZooAnimal
Компилятор даже не пытается как-то различать базовые классы. Преобразования в каждый из базовых классов происходят одинаково успешно. Рассмотрим, например, перегруженную версию функции print()
:
void print(const Bear&);
void print(const Endangered&);
Вызов функции print()
без квалификации для объекта класса Panda
приведет к ошибке во время выполнения.
Panda ying_yang("ying_yang");
print(ying_yang); // ошибка: неоднозначность
Как и при одиночном наследовании, статический тип объекта, указателя или ссылки определяет, какие из членов можно использовать. Если используется указатель класса ZooAnimal
, для применения будут пригодны только те функции, которые определены в этом классе. Части интерфейса класса Panda
, специфические для классов Bear
, Panda
и Endangered
, окажутся недоступны. Аналогично указатель или ссылка на класс Bear
применимы только для доступа к членам классов Bear
и ZooAnimal
, а указатель или ссылка на класс Endangered
ограничены лишь членами класса Endangered
.
В качестве примера рассмотрим следующие вызовы с учетом того, что эти классы определяют виртуальные функции, перечисленные в табл. 18.1.
Bear *pb = new Panda("ying_yang");
pb->print(); // ok: Panda::print()
pb->cuddle(); // ошибка: не является частью интерфейса Bear
pb->highlight(); // ошибка: не является частью интерфейса Bear
delete pb; // ok: Panda::~Panda()
Когда объект класса Panda
используется при помощи указателя или ссылки на класс Endangered
, части объекта класса Panda
, специфические для классов Panda
и Bear
, становятся недоступными.
Endangered *ре = new Panda("ying_yang");
pe->print(); // ok: Panda::print()
pe->toes(); // ошибка: не является частью интерфейса Endangered
pe->cuddle(); // ошибка: не является частью интерфейса Endangered
pe->highlight(); // ok: Panda::highlight()
delete pe; // ok: Panda::~Panda()
Таблица 18.1. Виртуальные функции иерархии классов ZooAnimal
/ Endangered
Функция | Класс, определяющий собственную версию |
---|---|
print() |
ZooAnimal::ZooAnimal |
Bear::Bear |
|
Endangered::Endangered |
|
Panda::Panda |
|
highlight |
Endangered::Endangered |
Panda::Panda |
|
toes |
Bear::Bear |
Panda::Panda |
|
cuddle |
Panda::Panda |
Деструктор | ZooAnimal::ZooAnimal |
Endangered::Endangered |
Упражнение 18.23. Используя иерархию из упражнения 18.22, а также определенный ниже класс D
и c учетом наличия у каждого класса стандартного конструктора, укажите, какие из следующих преобразований недопустимы (если таковые вообще имеются)?
class D : public X, public С { ... };
D *pd = new D;
(a) X *px = pd; (b) A *pa = pd;
(с) B *pb = pd; (d) C *pc = pd;
Упражнение 18.24. Выше представлена последовательность вызовов через указатель на класс Bear
, указывающих на объект класса Panda
. Объясните каждый вызов, подразумевая, что вместо него используется указатель на класс ZooAnimal
, указывающий на объект класса Panda
.
Упражнение 18.25. Предположим, существуют два базовых класса, Base1
и Base2
, в каждом из которых определена виртуальная функция-член по имени print()
и виртуальный деструктор. От этих базовых классов были получены следующие классы, в каждом из которых переопределена функция print()
.
class D1 : public Base1 { /* ... */ };
class D2 : public Base2 { /* ... */ };
class MI : public D1, public D2 {/* ... */ };
Используя следующие определения, укажите, какая из функций используется при каждом вызове:
Base1 *pb1 = new MI;
Base2 *pb2 = new MI;
D1 *pd1 = new MI;
D2 *pd2 = new MI;
(a) pb1->print(); (b) pd1->print(); (c) pd2->print();
(d) delete pb2; (e) delete pd1; (f) delete pd2;
18.3.3. Область видимости класса при множественном наследовании
При одиночном наследовании область видимости производного класса вкладывается в пределы его прямых и косвенных базовых классов (см. раздел 15.6). Поиск имен осуществляется по всей иерархии наследования. Имена, определенные в производном классе, скрывают совпадающие имена в базовом классе.
При множественном наследовании поиск осуществляется одновременно во всех прямых базовых классах. Если имя находится в нескольких базовых классах, происходит ошибка неоднозначности.
В рассматриваемом примере, если имя используется через указатель, ссылку или объект класса Panda
, деревья иерархии Endangered
и Bear
/ ZooAnimal
исследуются параллельно. Если имя находится в нескольких иерархиях, то возникнет неоднозначность. Для класса вполне допустимо наследовать несколько членов с тем же именем. Но если это имя необходимо использовать, следует указать, какая именно версия имеется в виду.
Интервал:
Закладка: