Скотт Майерс - Эффективное использование 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 верных способов улучшить структуру и код ваших программ - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Скотт Майерс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

C++ не принимает ничью сторону в этом споре. Он успешно поддерживает оба варианта, хотя по умолчанию предполагается дублирование. Если это не то, что вам нужно, сделайте класс, содержащий данные (то есть File), виртуальным базовым классом. Для этого все непосредственные потомки должны использовать виртуальное наследование:

class File class InputFile virtual public File class - фото 11

class File {...};

class InputFile: virtual public File {...};

class OutputFile: virtual public File {...};

class IOFile: public InputFile,

public OutputFile

{...};

В стандартной библиотеке C++ есть похожая иерархия, только классы в ней являются шаблонными и называются basic_ios, basic_istream, basic_ostream и basic_iostream, в не File, InputFile, OutputFile и IOFile.

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

Оно обходится не бесплатно еще и по другой причине. Правила, определяющие инициализацию виртуальных базовых классов, сложнее и интуитивно не так понятны, как правила для невиртуальных базовых классов. Ответственность за инициализацию виртуального базового класса ложится на самый дальний производный класс в иерархии. Отсюда следует, что: (1) классы, наследующие виртуальному базовому и требующие инициализации, должны знать обо всех своих виртуальных базовых классах, независимо от того, как далеко они от них находятся в иерархии, и (2) когда в иерархию добавляется новый производный класс, он должен принять на себя ответственность за инициализацию виртуальных предков (как прямых, так и непрямых).

Мой совет относительно виртуальных базовых классов (то есть виртуального наследования) прост. Во-первых, не применяйте виртуальных базовых классов до тех пор, пока в этом не возникнет настоятельная потребность. По умолчанию используйте невиртуальное наследование. Во-вторых, если все же избежать виртуальных базовых классов не удается, старайтесь не размещать в них данных. Тогда можно будет забыть о странностях правил инициализации (да, кстати, и присваивания) таких классов. Неспроста интерфейсы Java и. NET, которые во многом подобны виртуальным базовым классам C++, не могут содержать никаких данных.

Теперь рассмотрим следующий интерфейсный класс C++ (см. правило 31) для моделирования физических лиц:

class IPerson {

public:

virtual ~IPerson();

virtual std::string name() const = 0;

virtual std::string birthDate() const = 0;

};

Пользователи IPerson должны программировать в терминах указателей и ссылок на IPerson, поскольку создавать объекты абстрактных классов запрещено. Для создания объектов, которыми можно манипулировать как объектами IPerson, используются функции-фабрики (опять же см. правило 31), которые порождают объекты конкретных классов, производных от IPerson:

// функция-фабрика для создания объекта Person по уникальному

// идентификатору из базы данных; см. в правиле 18,

// почему возвращаемый тип – не обычный указатель

std::tr1::shared_ptr makePerson(DatabaseID personIdentifier);

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

DatabaseID askUserForDtabaseID();

DatabaseID id(askUserForDtabaseID());

std::tr1::shared_ptr pp(makePerson(id)); // создать объект,

// поддерживающий

// интерфейс IPerson

... // манипулировать *pp

// через функции-члены

// IPerson

Но как makePerson создает объекты, на которые возвращает указатель? Ясно, что должен быть какой-то конкретный класс, унаследованный от IPerson, который makePerson может инстанцировать.

Предположим, этот класс называется CPerson. Будучи конкретным классом, CPerson должен предоставлять реализацию чисто виртуальных функций, унаследованных от IPerson. Можно написать его «с нуля», но лучше воспользоваться уже готовыми компонентами, которые делают большую часть работы. Например, предположим, что старый, ориентированный только на базы данных класс Person-Info предоставляет почти все необходимое CPerson:

class PersonInfo {

public:

explicit PersonInfo(DatabaseID pid)

virtual ~PersonInfo();

virtual const char *theName() const;

virtual const char *theBirthDate() const;

...

private:

virtual const char *valeDelimOpen() const; // ñì. íèæå

virtual const char *valeDelimClose() const;

...

};

Понять, что этот класс старый, можно хотя бы потому, что функции-члены возвращают const char* вместо объектов string. Но если ботинки подходят, почему бы не носить их? Имена функций-членов класса наводят на мысль, что результат может оказаться вполне удовлетворительным.

Вскоре вы приходите к выводу, что класс PersonInfo был спроектирован для печати полей базы данных в различных форматах, с выделением начала и конца каждого поля специальными строками-разделителями. По умолчанию открывающим и закрывающим разделителями служат квадратные скобки, поэтому значение поля «Ring-tailed Lemur» будет отформатировано так:

[Ring-tailed Lemur]

Учитывая тот факт, что квадратные скобки не всегда приемлемы для пользователей PersonInfo, в классе предусмотрены виртуальные функции valeDelimOpen и valeDelimClose, позволяющие производным классам задать другие открывающие и закрывающие строки-разделители. Функции-члены PersonInfo вызывают эти виртуальные функции для добавления разделителей к возвращаемым значениям. Так, функция PersonInfo::theName могла бы выглядеть следующим образом:

const char *PersonInfo::valueDelimOpen() const

{

return “[“; // открывающий разделитель по умолчанию

}

const char *PersonInfo::valueDelimClose() const

{

return “]“; // закрывающий разделитель по умолчанию

}

const char * PersonInfo::theName() const

{

// резервирование буфера для возвращаемого значения; поскольку он

// статический, автоматически инициализируется нулями

static char value[Max_Formatted_Field_Value_Length];

// скопировать открывающий разделитель

std::strcpy(value, valueDelimOpen());

добавить к строке value значение из поля name объекта (будьте осторожны –

избегайте переполнения буфера!)

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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