Бьярне Страуструп написал об этом here.
Соответствующий бит по ссылке:
Могу ли я остановить людей, вытекающие из моего класса?
Да, но зачем вы хотите? Есть два общих ответа:
- для эффективности: во избежание моей функции звонки виртуальные.
- для безопасности: чтобы убедиться, что мой класс не используется в качестве базового класса а (например, чтобы быть уверенным , что я могу копировать объекты без страха нарезки)
По моему опыту, эффективность причиной обычно является неуместный страх. В 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
(from D&E sec 11.4.3).
Ага, и это может быть статический метод фабрики моего класса, чтобы держать вещи вместе? Звучит очень хорошо. – SebastianK
Unfoprto, к счастью, это не останавливает вывод.Это просто предотвращает создание производного типа, за исключением фабрики. Было бы неплохо, если бы вы могли на самом деле pprevent деривации, но, насколько мне известно, вы не можете. – 2009-06-16 11:43:41
В каком практическом смысле существует разница между невозможностью создания объекта производного типа и невозможности получения вообще (доступ к защищенным статическим членам?) – Motti