Эффективное использование STL | страница 21



>map

> vector::iterator,

> CIStringCompare>// ClStringCompare - сравнение строк

> // без учета регистра: см. совет 19

и вы хотите перебрать элементы множества при помощи >const_iterator. Захочется ли вам вводить строку

>map::iterator,CIStringCompare>::const_iterator

больше одного раза? После непродолжительной работы в STL вы поймете, что >typedef — ваш друг.

>Typedef всего лишь определяет синоним для другого типа, поэтому инкапсуляция производится исключительно на лексическом уровне. Она не помешает клиенту сделать то, что он мог сделать ранее (и не позволит сделать то, что было ранее недоступно). Если вы захотите ограничить зависимость клиента от выбранного типа контейнера, вам понадобятся более серьезные средства — классы.

Чтобы ограничить объем кода, требующего модификации при замене типа контейнера, скройте контейнер в классе и ограничьте объем информации, доступной через интерфейс класса. Например, если вам потребуется создать список клиентов, не используйте класс >list напрямую, определите класс >CustomerList и инкапсулируйте >list в его закрытой части:

>class CustomerList {

>private:

> typedef list CustomerContainer;

> typedef CustomerContainer::iterator CCIterator;

> CustomerContainer customers:

>public: // Объем информации, доступной

> // через этот интерфейс, ограничивается

>};

На первый взгляд происходящее выглядит глупо. Ведь список клиентов — это список, не правда ли? Вполне возможно. Но в будущем может оказаться, что возможность вставки-удаления в середине списка используется не так часто, как

предполагалось вначале, зато нужно быстро выделить 20% клиентов с максимальным объемом сделок — эта задача просто создана для алгоритма >nthelement (совет 31). Однако >nthelement требует итератора произвольного доступа и не будет работать с контейнером >list. В этой ситуации «список» лучше реализовать на базе >vector или >deque.

Рассматривая подобные изменения, необходимо проанализировать все функции класса >CustomerList, а также всех «друзей» (>friend) и посмотреть, как на них отразится это изменение (в отношении быстродействия, недействительности итераторов/указателей/ссылок и т. д.), но при грамотной инкапсуляции деталей реализации >CustomerList это изменение практически не повлияет на клиентов >CustomerList.

Совет 3. Реализуйте быстрое и корректное копирование объектов в контейнерах

В контейнерах хранятся объекты, но не те, которые вы им передаете. Более того, при получении объекта из контейнера вам предоставляется не тот объект, который находился в контейнере. При включении объекта (вызовом