views:

128

answers:

3

Is it possible to make my member functions final as in Java, so that the derived classes can not override them?

+6  A: 

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).

Péter Török
if i didn't misunderstood, then 'Overriding' is to hide the base class' copy, which is very much possible in this case.What I want is to force the derived classes to always use/call the base class' copy of function.
Hemant
@Hemant, see the links and code example I added.
Péter Török
I don't know Java, but from what I heard I thought in Java you were unable to even declare `D::mf()`.
sbi
@sbi, yes, that's correct. Trying to override a `final` method in Java results in a compiler error. So the default C++ behaviour is not equivalent to that of `final` in Java, although AFAIK many C++ compilers issue a warning about method hiding.
Péter Török
I think ... I almost got the rationale. +1 for referring 'Effective C++', it clears the doubts.
Hemant
There's another trick to prevent inheritance, which is to add a virtual base class which (a) has a private constructor, and (b) declares your class a `friend`. Constructors of virtual bases must be accessible to the most-derived class, so any derived class of your class can't be instantiated (although it can be defined). But, your class can be instantiated, so unlike your version you don't end up with a heap-only class. Can be done as a CRTP template. Downside: might make the objects bigger.
Steve Jessop
+3  A: 

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

Chubsdad
A [direct](http://www2.research.att.com/~bs/bs_faq2.html#no-derivation) link could have been more useful :p.
Stephen
@Stephen: I put it in. @chubsdad: I hope you don't mind.
sbi
@sbi: Oh, yeah, edit rights. I have those now. I forgot. >_<.
Stephen
but i ask about preventing the member function, not the whole class from being sub-classed.
Hemant
A: 

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

Sergius