Вход/Регистрация
Эффективное использование STL
вернуться

Мейерс Скотт

Шрифт:

}; // отсечения

Мы выделяем все данные и виртуальные функции в класс реализации и создаем компактный, мономорфный класс, содержащий указатель на класс реализации:

template<typename T> //Новый класс реализации

class BPFCImpl { //для измененного BPFC.

private:

 Widget w; // Все данные, ранее находившиеся

 int х; // в BPFC, теперь размещаются

 … // в этом классе,

 virtual ~BPFCImpl; // В полиморфных классах нужен

// виртуальный деструктор,

 virtual void operator(const T& val) const;

 friend class BPFC<T>; // Разрешить BPFC доступ к данным

};

template<typename T>

class BPFC: // Компактная, мономорфная версия

 public unary_function<T, void> {

private:

 BPFCImpl<T>* pImpl; // Все данные BPFC

public:

 void operator(const T& val) const; // Функция не является

 { // виртуальной; вызов передается

plImpl->operator(val); // BPFCImpl

 }

};

Реализация

BFPC::operator
дает пример того, как должны строиться реализации всех виртуальных функций
BPFC
: они должны вызывать свои виртуальные «прототипы» из
BPFCImpl
. Полученный в результате класс функтора (
BPFC
) компактен и мономорфен, но при этом он предоставляет доступ к большому объему данных состояния и работает полиморфно.

Материал изложен довольно кратко, поскольку описанные базовые приемы хорошо известны в кругах C++. В книге «Effective C++» этой теме посвящен совет 34. В книге «Приемы объектно-ориентированного проектирования» [6] соответствующая методика называется «паттерн Bridge». Саттер в своей книге «Exceptional C++» [8] использует термин «идиома

Pimpl
».

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

BPFC
, то вам пришлось бы позаботиться о том, чтобы копирующий конструктор выполнял осмысленные действия с объектом
BPFCImpl
, на который он ссылается. Возможно, простейшее решение заключается в организации подсчета ссылок при помощи указателя
shared_ptr
из библиотеки
Boost
или его аналога (см. совет 50).

В сущности, копирующий конструктор

BPFC
— единственное, о чем вам придется побеспокоиться в контексте данного примера, поскольку при передаче и получении функторов от функций STL всегда происходит копирование (помните, что говорилось выше о передаче по значению?). Из этого вытекают два требования: компактность и мономорфизм.

Совет 39. Реализуйте предикаты в виде «чистых» функций

Для начала разберемся с основными терминами.

• Предикатом называется функция, возвращающая тип

bool
(или другое значение, которое может быть автоматически преобразовано к
bool
). Предикаты широко используются в STL. В частности, функции сравнения в стандартных ассоциативных контейнерах представляют собой предикаты. Предикатные функции часто передаются в виде параметров таким алгоритмам, как
find_if
, и различным алгоритмам сортировки (обзор алгоритмов сортировки приведен в совете 31).

• «Чистой» функцией называется функция, возвращаемое значение которой зависит только от параметров. Если

f
— «чистая» функция, а 
x
и 
y
— объекты, то возвращаемое значение
f(x, y)
может измениться только в случае изменения х или у.

В C++ все данные, используемые «чистыми» функциями, либо передаются в виде параметров, либо остаются постоянными на протяжении всего жизненного цикла функции (естественно, такие постоянные данные объявляются с ключевым словом const). Если бы данные, используемые «чистой» функцией, могли изменяться между вызовами, то вызов этой функции в разные моменты времени с одинаковыми параметрами мог бы давать разные результаты, что противоречит определению «чистой» функции.

  • Читать дальше
  • 1
  • ...
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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