Вот недавно всплыл такой вопрос: можно ли запретить наследование от класса в С++. В Java есть такое понятие как final класс, т.е. класс от которого нельзя наследоваться.
Предположим есть некий класс А:
class A
{
public:
A(){}
~A(){}
};
и класс B
class B : public A //все отлично собирается
{
};
Необходимо сделать так, чтобы при попытке наследование компилятор выдавал сообщение об ошибке.
Первое, что приходит в голову это сделать конструктор и деструктор класса А приватными. Действительно после этого я не смогу наследоваться, но возникает другая проблема - я не могу создавать экземпляры класса А.
Пытаемся развить мысль далее. Что если переопределить для класса А операторы new и delete. Так как это будут операторы класса, то они смогут получить доступ к приватным конструктору и деструктору. Получается вот такой класс:
class A
{
private:
A(){}
~A(){}
public:
void* operator new(size_t size)
{
return ::operator new(size);
}
void operator delete(void* block)
{
::operator delete(block);
}
};
сlass B : public A //компилятор ругается
{
};
Но на самом деле это не работает. Переопределенные операторы new\delete все равно не получают доступа к приватным конструктору и деструктору класса А. Объявление операторов new\delete друзьями класса А тоже не помогает.
Второй мыслью (после часа попыток) было полезть во всемирную паутину и найти ответ там. Ответ я нашел, но не на все вопросы. Итак реализация final класса для С++ выглядит следующим образом:
class ClassLocker
{
friend class A;
private:
ClassLocker(){}
};
class A : public virtual ClassLocker
{
public:
A(){}
~A(){}
};
class B : public A //компилятор выдает сообщение об ошибке
{
};
Самое интересное, что если мы убрать виртуальное наследование класса А от класса ClassLocker, т.е. написать class A : public ClassLocker, то все отлично собирается. Слово virtual в данном случае является ключевым.
Итак в итоге есть два вопроса:
- Почему переопределенные операторы new\delete не имеют доступа к приватном конструктору и деструктору?
- Почему именно виртуальное наследование запрещает дальнейшее наследование?
Ответы на вопросы я дам в следующей статье.
Всем доброй ночи.
Комментариев нет:
Отправить комментарий