Есть два способа, простой дешевый и правильный.Два ответа @Naveen и @Nawaz связаны с правильным ответом, который требует ручного создания класса sealer для каждого класса, который вы действительно хотите запечатать.
Не дуракспособ, который используется в библиотеках Adobe использует шаблонный класс для этого.Проблема в том, что вы не можете объявить аргумент шаблона как друга, и это означает, что вам придется переключиться с private
на менее безопасный protected
:
template <typename T>
class sealer {
protected: sealer() {}
};
class sealed : virtual sealer<sealed> {};
И вы можете автоматизировать его с помощьюмакрос (я не помню точный вид макроса в коде Adobe):
#define seal( x ) virtual sealer<x>
class sealed : seal(sealed)
{};
Теперь это поймает людей, которые по ошибке пытаются наследовать, не зная, что они не должны:
class derived : sealed {};
int main() {
derived d; // sealer<T>::sealer() is protected within this context
}
Но это не помешает людям, которые действительно хотят получить, поскольку они могут получить доступ к конструктору, производя от самого шаблона:
class derived : sealed, sealer<sealed> {};
int main() {
derived d;
};
ЯЯ не уверен, изменится ли это в C ++ 0x, думаю, я вспомнил некоторые дискуссии о том, можно ли разрешить шаблону класса подружиться с одним из его аргументов, но в ходе краткого поиска по черновику я не могу точно сказать.Если бы это было разрешено, то это было бы хорошим общим решением:
template <typename T>
class sealer {
sealer() {}
friend class T; // Incorrect in C++03
};