Бьярне Страуструп написал об этом здесь .
Соответствующий бит из ссылки:
Могу ли я остановить людей, выходящих из моего класса?
Да, но почему вы хотите? Есть два общих ответа:
- для эффективности: чтобы избежать моей функции
звонки виртуальны.
- в целях безопасности: чтобы мой класс не использовался как
базовый класс (например, чтобы быть уверенным
что я могу копировать объекты без страха
нарезки)
По моему опыту, причиной эффективности обычно является неуместный страх. В C ++ вызовы виртуальных функций настолько быстры, что их реальное использование для класса, созданного с помощью виртуальных функций, не приводит к измеримым накладным расходам времени выполнения по сравнению с альтернативными решениями, использующими обычные вызовы функций. Обратите внимание, что механизм вызова виртуальной функции обычно используется только при вызове через указатель или ссылку. При вызове функции непосредственно для именованного объекта накладные расходы на класс виртуальной функции легко оптимизируются.
Если существует реальная необходимость «ограничить» иерархию классов, чтобы избежать вызовов виртуальных функций, можно спросить, почему эти функции являются виртуальными. Я видел примеры, когда критичные к производительности функции были сделаны виртуальными без уважительной причины, просто потому, что «мы так обычно делаем».
Другой вариант этой проблемы, как предотвратить вывод по логическим причинам, имеет решение. К сожалению, это решение не красиво. Он основан на том факте, что самый производный класс в иерархии должен создавать виртуальную базу. Например:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
(из D & E sec 11.4.3).