开发者

How to define 'final' member functions for a class

开发者 https://www.devze.com 2023-01-13 22:46 出处:网络
Is it possib开发者_开发知识库le to make my member functions final as in Java, so that the derived classes can not override them?C++11 adds a final contextual keyword to support this:

Is it possib开发者_开发知识库le to make my member functions final as in Java, so that the derived classes can not override them?


C++11 adds a final contextual keyword to support this:

class B
{
  public:
    virtual void foo() final;
};
class D : B
{
  public:
    virtual void foo(); // error: declaration of 'foo' overrides a 'final' function
};

final is supported in GCC 4.7 and Clang 3.0. And as Sergius notes in his answer, MSVC++ supports it (with the spelling sealed), since MSVC++2005. So if you encapsulate in a mini-macro and set it depending on your compiler, you can be on your way with this. Just make sure you actually are using such a compiler at least every so often, so you'll detect any mistakes early.


It is so much possible that it is in fact the default behaviour. I.e. if you don't declare your class instance methods explicitly as virtual, they can't be overridden in subclasses (only hidden, which is a different - and almost always erroneous - case).

Effective C++ Third Edition, Item 36 deals with this in detail. Consider

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)

So this is not exactly how final behaves in Java, but you can only get this close with C++. An alternative might be to prevent subclassing altogether. The technical - working, but not nice - solution to this is to declare all your constructors private (and provide a static factory method if you want to allow instantiation of your class, of course).


Check this from Bjarne (Can I stop people deriving from my class?)


Actually it is possible if you are using MSVC. There is a sealed keyword. Here is an example from msdn.


New C++11 standard now supports explicit overrides and final of member functions!

0

精彩评论

暂无评论...
验证码 换一张
取 消