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

Тут можно читать онлайн Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство Литагент «ДМК»233a80b4-1212-102e-b479-a360f6b39df7, год 2006. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
  • Автор:
  • Жанр:
  • Издательство:
    Литагент «ДМК»233a80b4-1212-102e-b479-a360f6b39df7
  • Год:
    2006
  • Город:
    Москва
  • ISBN:
    5-94074-304-8
  • Рейтинг:
    3.6/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

Издание ориентировано на программистов, знакомых с основами C++ и имеющих навыки его практического применения.

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

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

Интервал:

Закладка:

Сделать

Тот факт, что ps, pc и pr являются указателями, не играет никакой роли. Будь они ссылками, результат остался бы таким же. Важно лишь, что draw – виртуальная функция, и значение по умолчанию одного из ее аргументов переопределено в производном классе.

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

Все это прекрасно, но посмотрите, что получится, если, пытаясь следовать этому правилу, вы включите аргументы со значениями по умолчанию в функцию-член, объявленную и в базовом, и в производном классах:

class Shape {

public:

enum ShapeColor { Red, Green, Blue };

virtual void draw(ShapeColor color = Red) const = 0;

...

};

class Rectangle: public Shape {

public:

virtual void draw(ShapeColor color = Red) const;

...

};

Гм, дублирование кода! Хуже того: дублирование кода с зависимостями: если значение аргумента по умолчанию изменится в Shape, придется изменить его и во всех производных классах. В противном случае дело закончится переопределением наследуемого значения по умолчанию. Что делать?

Когда у вас возникает проблема с тем, чтобы заставить виртуальную функцию вести себя так, как вы хотите, то благоразумнее рассмотреть альтернативные решения, и в правиле 35 таких альтернатив приведено немало. Одна из них – идиома невиртуального интерфейса (NVI): определить в базовом классе открытую невиртуальную функцию, которая вызывает закрытую виртуальную функцию, переопределяемую в подклассах. В данном случае можно предложить невиртуальную функцию с аргументом по умолчанию и виртуальную функцию, которая выполняет всю реальную работу:

class Shape {

public:

enum ShapeColor( Red, Green, Blue };

void draw(ShapeColor color = Red) const // теперь – невиртуальная

{

doDraw(color); // вызов виртуальной функции

}

...

private:

virtual void doDraw(ShapeColor color) const = 0; // реальная работа

}; // выполняется

// в этой функции

class Rectangle: public Shape {

public:

...

private:

virtual void doDraw(ShapeColor color) const // обратите внимание

... // на отсутствие у аргумента

}; // значения по умолчанию

Поскольку невиртуальные функции никогда не должны переопределяться в производных классах (см. правило 36), то ясно, что при таком подходе значение по умолчанию для параметра color функции draw всегда будет Red.

Что следует помнить

• Никогда не переопределяйте наследуемые значения аргументов по умолчанию, потому что аргументы по умолчанию связываются статически, тогда как виртуальные функции – а только их и можно переопределять, – динамически.

Правило 38: Моделируйте отношение «содержит» или «реализуется посредством» с помощью композиции

Композиция – это отношение между типами, которое возникает тогда, когда объект одного типа содержит в себе объекты других типов. Например:

class Address {...}; // адрес проживания

class PhoneNumber {...};

class Person {

public:

...

private:

std::string name; // вложенный объект

Address address; // то же

PhoneNumber voiceNumber; // то же

PhoneNumber faxNumber; // то же

};

В данном случае объекты класса Person включают в себя объекты классов string, Address и PhoneNumber. Термин композиция имеет ряд синонимов, например: вложение, агрегирование или встраивание.

В правиле 32 объясняется, что открытое наследование означает «класс является разновидностью другого класса». У композиции тоже есть семантика, даже две: «содержит» или «реализуется посредством». Дело в том, что в своих программах вы имеете дело с двумя различными областями. Некоторые программные объекты описывают сущности из моделируемого мира: людей, автомобили, видеокадры и т. п. Такие объекты являются частью предметной области. Другие объекты возникают как часть реализации, например: буферы, мьютексы, деревья поиска и т. д. Они относятся к области реализации, свойственной для вашего приложения. Когда отношение композиции возникает между объектами из предметной области, оно имеет семантику «реализовано посредством».

Вышеприведенный класс Person демонстрирует отношение типа «содержит». Объект Person имеет имя, адрес, номера телефона и факса. Нельзя сказать, что человек «есть разновидность» имени или что человек «есть разновидность» адреса. Можно сказать, что человек «имеет» («содержит») имя и адрес. Большинство людей не испытывают затруднений при проведении подобных различий, поэтому путаница между ролями «является» и «содержит» возникает сравнительно редко.

Чуть сложнее провести различие между отношениями «является» и «реализуется посредством». Например, предположим, что вам нужен шаблон для классов, представляющих множества произвольных объектов, то есть наборов без дубликатов. Поскольку повторное использование – прекрасная вещь, то сразу возникает желание обратиться к шаблону set из стандартной библиотеки. В конце концов, зачем писать новый шаблон, когда есть возможность использовать уже готовый?

К сожалению, реализации set обычно влекут за собой накладные расходы – по три указателя на элемент. Связано это с тем, что множества обычно реализованы в виде сбалансированных деревьев поиска, гарантирующих логарифмическое время поиска, вставки и удаления. Когда быстродействие важнее, чем объем занимаемой памяти, это вполне разумное решение, но конкретно для вашего приложения выясняется, что экономия памяти более существенна. Поэтому стандартный шаблон set для вас неприемлем. Похоже, нужно писать свой собственный.

Тем не менее повторное использование – прекрасная вещь. Будучи экспертом в области структур данных, вы знаете, что среди многих вариантов реализации множеств есть и такой, который базируется на применении связанных списков. Вы также знаете, что в стандартной библиотеке C++ есть шаблон list, поэтому решаете им воспользоваться (повторно).

В частности, вы решаете, что создаваемый вами шаблон Set должен наследовать от list. То есть Set будет наследовать list. В итоге в вашей реализации объект Set будет выступать как объект list. Соответственно, вы объявляете Set следующим образом:

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

Интервал:

Закладка:

Сделать


Скотт Майерс читать все книги автора по порядку

Скотт Майерс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x