Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация

Тут можно читать онлайн Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Издательский дом Вильямс, год 2005. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Стандарты программирования на С++. 101 правило и рекомендация
  • Автор:
  • Жанр:
  • Издательство:
    Издательский дом Вильямс
  • Год:
    2005
  • Город:
    Москва
  • ISBN:
    5-8459-0859-0
  • Рейтинг:
    3.3/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 60
    • 1
    • 2
    • 3
    • 4
    • 5

Герб Саттер - Стандарты программирования на С++. 101 правило и рекомендация краткое содержание

Стандарты программирования на С++. 101 правило и рекомендация - описание и краткое содержание, автор Герб Саттер, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

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

Опытные программисты найдут в ней советы и новые рекомендации, которые можно сразу же принять на вооружение. Программисты-профессионалы могут использовать эту книгу как основу для разработки собственных стандартов кодирования, как для себя лично, так и для группы, которой они руководят.

Конечно, книга рассчитана в первую очередь на профессиональных программистов с глубокими знаниями языка, однако она будет полезна любому, кто захочет углубить свои знания в данной области.

Стандарты программирования на С++. 101 правило и рекомендация - читать онлайн бесплатно полную версию (весь текст целиком)

Стандарты программирования на С++. 101 правило и рекомендация - читать книгу онлайн бесплатно, автор Герб Саттер
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Открытое наследование действительно связано с повторным использованием, но опять же не так, как привыкло думать множество программистов. Как уже указывалось, цель открытого наследования — в реализации заменимости (см. [Liskov88]). Цель отрытого наследования не в том, чтобы производный класс мог повторно использовать код базового класса для того, чтобы с его помощью реализовать свою функциональность. Такое отношение "реализован посредством" вполне корректно, но должно быть смоделировано при помощи композиции или, только в отдельных случаях, при помощи закрытого или защищенного наследования (см. рекомендацию 34).

Вот еще одно соображение по поводу рассматриваемой темы. При корректности и целесообразности динамического полиморфизма композиция "эгоистична" в отличие от "щедрого" наследования. Поясним эту мысль.

Новый производный класс представляет собой частный случай существующей более общей абстракции. Существующий (динамический) полиморфный код, который использует Base&или Base*путем вызова виртуальных функций Base, должен быть способен прозрачно использовать объекты класса MyNewDerivedType, производного от Base. Новый производный тип добавляет новую функциональность к существующему коду, который при этом не должен изменяться. Однако несмотря на неизменность имеющегося кода, при использовании им новых производных объектов его функциональность возрастает.

Новые требования, естественно, должны удовлетворяться новым кодом, но они не должны требовать внесения изменений в существующий код (см. рекомендацию 36).

До объектно-ориентированного программирования было легко решить вопрос вызова старого кода новым. Открытое наследование упростило прозрачный и безопасный вызов нового кода старым (так что применяйте шаблоны, предоставляющие возможности статического полиморфизма, который хорошо совместим с полиморфизмом динамическим — см. рекомендацию 64).

Исключения

Классы стратегий добавляют новое поведение путем открытого наследования, но это не является неверным употреблением открытого наследования для моделирования отношения "реализован посредством".

Ссылки

[Cargill92] pp. 19-20 • [Cline99] §5.13, §7.01-8.15 • [Dewhurst03] §92 • [Liskov88] • [Meyers97] §35 • [Stroustrup00] §12.4.1, §23.4.3.1, §24.3.4 • [Sutter00] §22-24

38. Практикуйте безопасное перекрытие

Резюме

Ответственно подходите в перекрытию функций. Когда вы перекрываете виртуальную функцию, сохраняйте заменимость; в частности, обратите внимание на пред- и постусловия в базовом классе. Не изменяйте аргументы по умолчанию виртуальных функций. Предпочтительно явно указывать перекрываемые функции как виртуальные. Не забывайте о сокрытии перегруженных функций в базовом классе.

Обсуждение

Хотя обычно производные классы добавляют новые состояния (т.е. члены-данные), они моделируют подмножества (а не надмножества) своих базовых классов. При корректном наследовании производный класс моделирует частный случай более общей базовой концепции (см. рекомендацию 37).

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

Определение в производном классе перекрытия, которое может быть неуспешным (например, генерировать исключения; см. рекомендацию 70), будет корректно только в том случае, когда в базовом классе не объявлено, что данная операция всегда успешна. Например, скажем, класс Employeeсодержит виртуальную функцию-член GetBuilding, предназначение которой — вернуть код здания, в котором работает объект Employee. Но что если мы захотим написать производный класс RemoteContractor, который перекрывает функцию GetBuilding, в результате чего она может генерировать исключения или возвращать нулевой код здания? Такое поведение корректно только в том случае, если в документации класса Employeeуказано, что функция GetBuildingможет завершаться неуспешно, и в классе RemoteContractorсообщение о неудаче выполняется документированным в классе Employeeспособом.

Никогда не изменяйте аргумент по умолчанию при перекрытии. Он не является частью сигнатуры функции, и клиентский код будет невольно передавать различные аргументы в функцию, в зависимости от того, какой узел иерархии обращается к ней. Рассмотрим следующий пример:

class Base {

// ...

virtual void Foo(int x = 0);

};

class Derived : public Base {

// ...

virtual void Foo(int x = 1); // лучше так не делать...

};

Derived *pD = new Derived;

pD->Foo(); // Вызов pD->Foo(1)

Base *pB = pD;

pB->Foo(); // вызов pB->Foo(0)

У некоторых может вызвать удивление, что одна и та же функция-член одного и того же объекта получает разные аргументы в зависимости от статического типа, посредством которого к ней выполняется обращение.

Желательно добавлять ключевое слово virtualпри перекрытии функций, несмотря на его избыточность — это сделает код более удобным для чтения и понимания.

Не забывайте о том, что перекрытие может скрывать перегруженные функции из базового класса, например:

class Base{ // ...

virtual void Foo(int);

virtual void Foo(int, int);

void Foo(int, int, int);

};

class Derived : public Base { // ...

virtual void Foo(int); // Перекрывает Base::Foo(int),

// скрывая остальные функции

};

Derived d;

d.Foo(1); // Все в порядке

d.Foo(1, 2); // Ошибка

d.Foo(1, 2, 3); // Ошибка

Если перегруженные функции из базового класса должны быть видимы, воспользуйтесь объявлением usingдля того, чтобы повторно объявить их в производном классе:

class Derived : public Base { // ...

virtual void Foo(int); // Перекрытие Base::Foo(int)

using Base::Foo; // вносит все прочие перегрузки

// Base::Foo в область видимости

};

Примеры

Пример: Ostrich (Страус). Если класс Bird(Птица) определяет виртуальную функцию Flyи вы порождаете новый класс Ostrich(известный как птица, которая не летает) из класса Bird, то как вы реализуете Ostrich::Fly? Ответ стандартный — "по обстоятельствам". Если Bird::Flyгарантирует успешность (т.е. обеспечивает гарантию бессбойности; см. рекомендацию 71), поскольку способность летать есть неотъемлемой частью модели Bird, то класс Ostrichоказывается неадекватной реализацией такой модели.

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

Интервал:

Закладка:

Сделать


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

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




Стандарты программирования на С++. 101 правило и рекомендация отзывы


Отзывы читателей о книге Стандарты программирования на С++. 101 правило и рекомендация, автор: Герб Саттер. Читайте комментарии и мнения людей о произведении.


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

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