Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
void clobber(Sneaky &s) { s.j = s.prot_mem = 0; }
// ошибка: clobber не может обращаться к защищенным членам Base
void clobber(Base &b) { b.prot_mem = 0; }
Если производные классы (и друзья) смогут обращаться к защищенным членам в объекте базового класса, то вторая версия функции clobber
(получающая тип Base&
) будет корректна. Хоть эта функция и не дружественна классу Base
, она все же сможет изменить объект типа Base
; для обхода защиты спецификатором protected
любого класса достаточно определить новый класс по линии Sneaky
.
Для предотвращения такого способа применения члены и друзья производного класса могут обращаться к защищенным членам только тех объектов базового класса, которые встроены в объект производного; к обычным объектам базового типа у них никакого доступа нет.
Доступ к члену наследуемого класса контролируется комбинацией спецификатора доступа этого члена в базовом классе и спецификатором доступа в списке наследования производного класса. Для примера рассмотрим следующую иерархию:
class Base {
public:
void pub_mem(); // открытый член
protected:
int prot_mem; // защищенный член
private:
char priv_mem; // закрытый член
};
struct Pub_Derv : public Base {
// ok: производный класс имеет доступ к защищенным членам
int f() { return prot_mem; }
// ошибка: закрытые члены недоступны производным классам
char g() { return priv_mem; }
};
struct Priv_Derv : private Base {
// закрытое наследование не затрагивает доступ в производном классе
int f1() const { return prot_mem; }
};
Спецификатор доступа наследования никак не влияет на возможность членов (и друзей) производного класса обратиться к членам его собственного прямого базового класса. Доступ к членам базового класса контролируется спецификаторами доступа в самом базовом классе. Структуры Pub_Derv
и Priv_Derv
могут обращаться к защищенному члену prot_mem
, но ни одна из них не может обратиться к закрытому члену priv_mem
.
Задача спецификатора доступа наследования — контролировать доступ пользователей производного класса, включая другие классы, производные от него, к членам, унаследованным от класса Base
:
Pub_Derv d1; // члены, унаследованные от Base, являются открытыми
Priv_Derv d2; // члены, унаследованные от Base, являются закрытыми
d1.pub_mem(); // ok: pub_mem является открытой в производном класс
d2.pub_mem(); // ошибка: pub_mem является закрытой в производном классе
Структуры Pub_Derv
и Priv_Derv
унаследовали функцию pub_mem()
. При открытом наследовании члены сохраняют свой спецификатор доступа. Таким образом, объект d1
может вызвать функцию pub_mem()
. В структуре Priv_Derv
члены класса Base
являются закрытыми; пользователи этого класса не смогут вызвать функцию pub_mem()
.
Спецификатор доступа наследования, используемый производным классом, также контролирует доступ из классов, унаследованных от этого производного класса:
struct Derived_from_Public : public Pub_Derv {
// ok: Base::prot_mem остается защищенной в Pub_Derv
int use_base() { return prot_mem; }
};
struct Derived_from_Private : public Priv_Derv {
// ошибка: Base::prot_mem является закрытой в Priv_Derv
int use_base() { return prot_mem; }
};
Классы, производные от структуры Pub_Derv
, могут обращаться к переменной-члену prot_mem
класса Base
, поскольку она остается защищенным членом в структуре Pub_Derv
. У классов, производных от структуры Priv_Derv
, напротив, такого доступа нет. Все члены, которые структура Priv_Derv
унаследовала от класса Base
, являются закрытыми.
Если бы был определен другой класс, скажем, Prot_Derv
, использующий защищенное наследование, открытые члены класса Base
в этом классе будут защищенными. У пользователей структуры Prot_Derv
не было бы никакого доступа к функции pub_mem()
, но ее члены и друзья могли бы обратиться к унаследованному члену.

Будет ли доступно преобразование производного класса в базовый класс (см. раздел 15.2.2), зависит от того, какой код пытается использовать преобразование, а также от спецификатора доступа, используемого при наследовании производного класса. С учетом, что класс D
происходит от класса B
:
• Пользовательский код может использовать преобразование производного класса в базовый, только если класс D
открыто наследует класс B
. Пользовательский код не может использовать преобразование, если наследование было защищенным или закрытым.
• Функции-члены и друзья класса D
могут использовать преобразование в В
независимо от вида наследования D
от B
. Преобразование производного в прямой базовый класс всегда доступно для членов и друзей производного класса.
• Функции-члены и друзья классов, производных от класса D
, могут использовать преобразование производного класса в базовый, если наследование было открытым или защищенным. Такой код не сможет использовать преобразование, если наследование классом D
класса В
было закрытым.
В любом месте кода, где доступен открытый член базового класса, будет доступно также преобразование производного класса в базовый, но не наоборот.
Без наследования у класса будет два разных вида пользователей: обычные пользователи и разработчики (implementor). Обычные пользователи пишут код, который использует объекты типа класса; такой код может обращаться только к открытым членам класса (интерфейсу). Разработчики пишут код, содержащийся в членах и друзьях класса. Члены и друзья класса могут обращаться и к открытым, и к закрытым разделам (реализации).
При наследовании появляется третий вид пользователей, а именно производные классы. Базовый класс делает защищенными те части своей реализации, которые позволено использовать его производным классам. Защищенные члены остаются недоступными обычному пользовательскому коду; закрытые члены остаются недоступными производным классам и их друзьям.
Подобно любому другому классу, базовый класс объявляет члены своего интерфейса открытыми. Класс, используемый как базовый, может разделить свою реализацию на члены, доступные для производных классов и доступные только для базового класса и его друзей. Член класса, относящийся к реализации, должен быть защищен, если он предоставляет функцию или данные, которые производный класс должен будет использовать в собственной реализации. В противном случае члены реализации должны быть закрытыми.
Читать дальшеИнтервал:
Закладка: