Риск освобождается через указатель на базовый класс ( delete , delete [] и, возможно, другие методы освобождения). Поскольку эти классы ( deque , map , string и т. Д.) Не имеют виртуальных dtors, их невозможно очистить должным образом, используя только указатель на эти классы:
struct BadExample : vector<int> {};
int main() {
vector<int>* p = new BadExample();
delete p; // this is Undefined Behavior
return 0;
}
Тем не менее, , если вы готовы убедиться, что никогда не сделаете это случайно, у них мало серьезных недостатков в их наследовании - но в некоторых случаях это большое условие. Другие недостатки включают конфликты со спецификой реализации и расширениями (некоторые из которых могут не использовать зарезервированные идентификаторы) и работу с раздутыми интерфейсами (в частности string ). Однако в некоторых случаях наследование предназначено, поскольку адаптеры контейнеров, такие как stack , имеют защищенный член c (базовый контейнер, который они адаптируют), и он почти доступен только из экземпляра производного класса.
Вместо наследования или композиции рассмотрите возможность написания свободных функций , которые принимают либо пару итераторов, либо ссылку на контейнер и оперируют с ней. Практически все из является примером этого; и make_heap , pop_heap и push_heap , в частности, являются примером использования свободных функций вместо контейнера для конкретного домена.
Итак, используйте классы-контейнеры для ваших типов данных и по-прежнему вызывайте бесплатные функции для вашей предметно-ориентированной логики. Но вы все равно можете добиться некоторой модульности, используя typedef, который позволяет вам упростить объявление их и обеспечивает единую точку, если часть из них должна измениться:
typedef std::deque<int, MyAllocator> Example;
// ...
Example c (42);
example_algorithm(c);
example_algorithm2(c.begin() + 5, c.end() - 5);
Example::iterator i; // nested types are especially easier
Обратите внимание, что value_type и allocator могут меняться, не влияя на более поздний код с использованием typedef, и даже контейнер может меняться с deque на vector .