Чтение онлайн

на главную - закладки

Жанры

Эффективное использование STL
Шрифт:

 void operator(int x){…} // в совете 40

};

typedef deque<int>::iterator DequeIntIter; // Вспомогательное определение

deque<int> di;

DoSomething d; // Создать объект функции

for_each<DequeIntIter, // Вызвать for_each с типами

 DoSomethng&>(di.begin, //
параметров DequeIntIter

 di.end, // и DoSomething&; в результате

 d); // происходит передача

// и возврат по ссылке.

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

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

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

Столь же нереалистичен и запрет на полиморфные функторы. Иерархическое наследование и динамическое связывание относятся к числу важнейших особенностей C++, и при проектировании классов функторов они могут принести такую же пользу, как и в других областях. Что такое классы функторов без наследования? C++ без «++». Итак, необходимы средства, которые бы позволяли легко передавать большие и/или полиморфные объекты функций с соблюдением установленного в STL правила о передаче функторов по значению.

Такие средства действительно существуют. Достаточно взять данные и/или полиморфные составляющие, которые требуется сохранить в классе функтора, перенести их в другой класс и сохранить в классе функтора указатель на этот новый класс. Рассмотрим пример создания класса полиморфного функтора с большим количеством данных:

template<typename T> // BPFC = "Big Polymorphic

class BPFC: // Functor class"

 public // Базовый класс описан

 unary_function<T, void> { // в совете 40

private:

 Widget w; //
Класс содержит большой объем

 int х; // данных, поэтому передача

 … // по значению

// была бы неэффективной

public:

 virtual void operator(const T& val) const; // Виртуальная функция.

 … // создает проблему

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

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

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
».

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

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Кодекс Охотника. Книга XIV

Винокуров Юрий
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XIV

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Я снова граф. Книга XI

Дрейк Сириус
11. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я снова граф. Книга XI

Болотник

Панченко Андрей Алексеевич
1. Болотник
Фантастика:
попаданцы
альтернативная история
6.50
рейтинг книги
Болотник

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Голодные игры

Коллинз Сьюзен
1. Голодные игры
Фантастика:
социально-философская фантастика
боевая фантастика
9.48
рейтинг книги
Голодные игры

Последняя Арена 8

Греков Сергей
8. Последняя Арена
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Последняя Арена 8

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона