Подтвердить что ты не робот

Как определить "конечные" функции-члены для класса

Возможно ли сделать мои функции-члены final такими же, как в Java, чтобы производные классы не могли их переопределить?

4b9b3361

Ответ 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 теперь поддерживает явные переопределения и окончание функций-членов!