Возможно ли сделать мои функции-члены final
такими же, как в Java, чтобы производные классы не могли их переопределить?
Как определить "конечные" функции-члены для класса
Ответ 1
Это настолько возможно, что на самом деле это поведение по умолчанию. То есть если вы не объявляете свои методы экземпляра класса явно как virtual
, они не могут быть overridden в подклассах (только hidden, который является другим - и почти всегда ошибочным -).
Эффективное С++ Third Edition, статья 36 подробно обсуждает это. Рассмотрим
class B {
public:
virtual void vf();
void mf();
virtual void mf(int);
...
};
class D: public B {
public:
virtual void vf(); // overrides B::vf
void mf(); // hides B::mf; see Item33
...
};
D x; // x is an object of type D
B *pB = &x; // get pointer to x
D *pD = &x; // get pointer to x
pD->vf(); // calls D::mf, as expected
pB->vf(); // calls D::mf, as expected
pD->mf(); // calls D::mf, as expected
pB->mf(); // calls B::mf - surprise!
pD->mf(1); // error - D::mf() hides B::mf(int)!
pB->mf(1); // calls B::mf(int)
Таким образом, это не совсем так, как final
ведет себя в Java, но вы можете приблизиться только к С++. Альтернативой может быть предотвращение подклассификации вообще. Технически - работающее, но не очень приятное решение - объявить все ваши конструкторы private
(и предоставить статический метод factory, если вы хотите, конечно, разрешить создание экземпляра своего класса).
Ответ 2
С++ 11 добавляет контекстное ключевое слово final
для поддержки этого:
class B
{
public:
virtual void foo() final;
};
class D : B
{
public:
virtual void foo(); // error: declaration of 'foo' overrides a 'final' function
};
final
поддерживается в GCC 4.7 и Clang 3.0. И, как отмечает Сергий в своем ответе, MSVС++ поддерживает его (с орфографией sealed
), начиная с MSVС++ 2005. Поэтому, если вы инкапсулируете в мини-макрос и установите его в зависимости от вашего компилятора, вы можете быть в пути с этим. Просто убедитесь, что вы на самом деле используете такой компилятор, по крайней мере, каждый раз так часто, чтобы обнаружить какие-либо ошибки раньше.
Ответ 3
Отметьте this от Bjarne (могу ли я остановить людей, происходящих из моего класса?)
Ответ 4
На самом деле это возможно, если вы используете MSVC. Существует ключевое слово sealed
. Ниже приведен пример из msdn.
Ответ 5
Новый стандарт С++ 11 теперь поддерживает явные переопределения и окончание функций-членов!