Yuri_p33 wrote:ballymahon wrote:8K wrote:Неужели нельзя "запечатать" класс собственными средствами С++? Не верю.
А как интересно? Можно конечно не использовать виртуальных функций и protected членов (о чем уже упоминалось) и тогда от наследования не будет особого толку, хотя сама возможность и будет присутствовать.
Как запретить наследование от данного класса - разве что сделать все конструкторы приватными и создавать обьекты статической функцией?
Примерно так:
Code: Select all
class Final
{
protected:
Final(int) {}
};
class MySealedClass: private virtual Final
{
public:
MySealedClass(): Final(0) {};
/* your code */
};
class MyDerivedClass: public MySealedClass
{
};
Хотя этот код скомпилируется, при попытке создать переменную типа MyDerivedClass компилятор пошлет нас подальше. Говорят, такой вопрос даже на интервью бывает
![Smile :)](./images/smilies/icon_smile.gif)
This solution is very clever, but, if a developer who really wants to derive from MySealedClass can always change MyDerivedClass so that the Final constructor is called explicitely, e.g.:
Code: Select all
class MyDerivedClass: public MySealedClass
{
public:
MyDerivedClass(): Final(0) {};
/* your code */
};
I think the following solution is a little bit better, because MySealedClass can only be derived from if the declaration of Final is changed. This prompts developer to think twice, especially if he/she did not write the MySealedClass class or does not control the source.
Code: Select all
class Final
{
private:
friend class MySealedClass;
Final() {}
};
class MySealedClass: private virtual Final
{
public:
MySealedClass() {};
/* your code */
};
class MyDerivedClass : public MySealedClass
{
public:
MyDerivedClass () {} //error here
/* your code */
};
int main(int argc, char* argv[])
{
MySealedClass a;
return 0;
}
In this case, the compilation of MyDerivedClass class fails (at least in Visual C++ v6) because MyDerivedClass can not access private constructor of Final.
Also, compilation fails even when no instances of MyDerivedClass are created.