Концепция абстрактного класса дает эффективное средство для разделения интерфейса и его реализации. Мы применяли эту концепцию и получали постоянную связь между интерфейсом, заданным абстрактным типом, и реализацией, представленной конкретным типом. Так, невозможно переключить абстрактный итератор с одного класса-источника на другой, например, если исчерпано множество (класс set), невозможно перейти на потоки.
Далее, пока мы работаем с объектами абстрактного типа с помощью указателей или ссылок, теряются все преимущества виртуальных функций. Программа пользователя начинает зависеть от конкретных классов реализации. Действительно, не зная размера объекта, даже при абстрактном типе нельзя разместить объект в стеке, передать как параметр по значению или разместить как статический. Если работа с объектами организована через указатели или ссылки, то задача распределения памяти перекладывается на пользователя (§13.10).
Существует и другое ограничение, связанное с использованием абстрактных типов. Объект такого класса всегда имеет определенный размер, но классы, отражающие реальное понятие, могут требовать память разных размеров.
Есть распространенный прием преодоления этих трудностей, а именно, разбить отдельный объект на две части: управляющую, которая определяет интерфейс объекта, и содержательную, в которой находятся все или большая часть атрибутов объекта. Связь между двумя частями реализуется с помощью указателя в управляющей части на содержательную часть. Обычно в управляющей части кроме указателя есть и другие данные, но их немного. Суть в том, что состав управляющей части не меняется при изменении содержательной части, и она настолько мала, что можно свободно работать с самими объектами, а не с указателями или ссылками на них.
управляющая часть содержательная часть
Простым примером управляющего класса может служить класс string из §7.6. В нем содержится интерфейс, контроль доступа и управление памятью для содержательной части. В этом примере управляющая и содержательная части представлены конкретными типами, но чаще содержательная часть представляется абстрактным классом.
Теперь вернемся к абстрактному типу set из §13.3. Как можно определить управляющий класс для этого типа, и какие это даст плюсы и минусы? Для данного класса set можно определить управляющий класс просто перегрузкой операции ->: