Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ

Здесь есть возможность читать онлайн «Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Москва, Год выпуска: 2006, ISBN: 2006, Издательство: Array Литагент «ДМК», Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Эта книга представляет собой перевод третьего издания американского бестселлера Effective C++ и является руководством по грамотному использованию языка C++. Она поможет сделать ваши программы более понятными, простыми в сопровождении и эффективными. Помимо материала, описывающего общую стратегию проектирования, книга включает в себя главы по программированию с применением шаблонов и по управлению ресурсами, а также множество советов, которые позволят усовершенствовать ваши программы и сделать работу более интересной и творческой. Книга также включает новый материал по принципам обработки исключений, паттернам проектирования и библиотечным средствам.
Издание ориентировано на программистов, знакомых с основами C++ и имеющих навыки его практического применения.

Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ — читать онлайн ознакомительный отрывок

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

void Derived::mf4()

{

...

mf2();

...

}

Когда компилятор видит имя mf2, он должен понять, на что оно ссылается. Для этого в различных областях видимости производится поиск имени mf2. Сначала оно ищется в локальной области видимости (то есть внутри mf4), но там такого имени нет. Тогда просматривается объемлющая область видимости, то есть область видимости класса Derived. И здесь такое имя отсутствует, поэтому компилятор переходит к следующей область видимости, которой является базовый класс. И находит там нечто по имени mf2, после чего поиск завершается. Если бы mf2 не было и в классе Base, то поиск продолжился бы сначала в пространстве имен, содержащем Base, если таковое имеется, и, наконец, в глобальной области видимости.

Данное мной описание правильно, хотя и исчерпывает всю сложность процесса поиска имен в C++. Наша цель, однако, не в том, чтобы узнать о поиске имен столько, чтобы самостоятельно написать компилятор. Достаточно будет, если мы сумеем избежать неприятных сюрпризов, а для этого изложенной информации должно хватить.

Снова вернемся к предыдущему примеру, но на этот раз перегрузим функции mf1 и mf3, а также добавим версию mf3 в класс Derived. Как объясняется в правиле 36, перегрузка mf3 в производном классе Derived (когда наследуется невиртуальная функция) сама по себе подозрительна, но чтобы лучше разобраться с видимостью имен, закроем на это глаза.

class Base private int x public virtual void mf1 0 virtual - фото 5

class Base {

private:

int x;

public:

virtual void mf1() = 0;

virtual void mf1(int);

virtual void mf2();

void mf3();

void mf3(double);

...

};

class Derived: public Base {

public:

virtual void mf1()

void mf3();

void mf4();

...

};

Этот код приводит к поведению, которое удивит любого программиста C++, впервые столкнувшегося с ним. Основанное на областях видимости правило сокрытия имен никуда не делось, поэтому все функции с именами mf1 и mf3 в базовом классе окажутся скрыты одноименными функциями в производном классе. С точки зрения поиска имен, Base::mf1 и Base::mf3 более не наследуются классом Derived!

Derived d;

int x;

...

d.mf1(); // правильно, вызывается Derived::mf1

d.mf1(x); // ошибка! Derived::mf1 скрывает Base::mf1

d.mf2(); // правильно, вызывается Base::mf2

d.mf3(); // правильно, вызывается Derived::mf3

d.mf3(x); // ошибка! Derived::mf3 скрывает Base::mf3

Как видите, это касается даже тех случаев, когда функции в базовом и производном классах принимают параметры разных типов, независимо от того, идет ли речь о виртуальных или невиртуальных функциях. И точно так же, как в нашем первом примере double x внутри функции someFunc скрывает int x из глобального контекста, так и здесь функция mf3 в классе Derived скрывает функцию mf3 из класса Base, которая имеет другой тип.

Обоснование такого поведения в том, что оно не дает нечаянно унаследовать перегруженные функции из базового класса, расположенного много выше в иерархии наследования, упрятанной в библиотеке или каркасе приложения. К сожалению, обычно вы хотите унаследовать перегруженные функции. Фактически если вы используете открытое наследование и не наследуете перегруженные функций, то нарушаете семантику отношения «является» между базовым и производным классами, которое в правиле 32 провозглашено фундаментальным принципом открытого наследования. То есть это тот случай, когда вы почти всегда хотите обойти принятое в C++ по умолчанию правило сокрытия имен.

Это можно сделать с помощью using-объявлений:

class Base private int x public virtual void mf1 0 virtual - фото 6

class Base {

private:

int x;

public:

virtual void mf1() = 0;

virtual void mf1(int);

virtual void mf2();

void mf3();

void mf3(double);

...

};

class Derived: public Base {

public:

using Base::mf1; // обеспечить видимость всех (открытых) имен

using Base::mf3; // mf1 и mf3 из класса Base в классе Derived

virtual void mf1()

void mf3();

void mf4();

...

};

Теперь наследование будет работать, как и ожидается.

Derived d;

int x;

...

d.mf1(); // по-прежнему правильно, вызывается Derived::mf1

d.mf1(x); // теперь правильно, вызывается Base::mf1

d.mf2(); // по-прежнему правильно, вызывается Base::mf2

d.mf3(); // по-прежнему правильно, вызывается Derived::mf3

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»

Представляем Вашему вниманию похожие книги на «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ»

Обсуждение, отзывы о книге «Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x