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

Майерс Скотт

Шрифт:

Теперь рассмотрим следующий интерфейсный класс 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<IPerson> makePerson(DatabaseID personIdentifier);

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

DatabaseID askUserForDtabaseID;

DatabaseID id(askUserForDtabaseID);

std::tr1::shared_ptr<IPerson> 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; // ~n`i. 'i`eaea

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 объекта (будьте осторожны –

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

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

  • Читать дальше
  • 1
  • ...
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • ...

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

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: