39

Is anyone aware of a language feature or technique in C++ to prevent a child class from over riding a particular method in the parent class?

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

Even though it's not virtual, this is still allowed (at least in the Metrowerks compiler I'm using), all you get is a compile time warning about hiding non-virtual inherited function X.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
Adam
  • 25,966
  • 23
  • 76
  • 87

14 Answers14

44

When you can use the final specifier for virtual methods (introduced with C++11), you can do it. Let me quote my favorite doc site:

When used in a virtual function declaration, final specifies that the function may not be overridden by derived classes.

Adapted to your example that'd be like:

class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

When compiled:

$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’

When you are working with a Microsoft compiler, also have a look at the sealed keyword.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • i removed virtual and it showed me error with base call function ... final works with only virtual functions? – abhimanyuaryan Apr 09 '15 at 22:25
  • @AbhimanyuAryan correct `final` only works with virtual methods so doesn't apply to this question – j b Jul 04 '19 at 08:13
  • 1
    And note that (at least in Visual C++) if you mark a const method as final it needs const final not final const. – tschumann Mar 22 '20 at 05:11
15

A couple of ideas:

  1. Make your function private.
  2. Do not make your function virtual. This doesn't actually prevent the function from being shadowed by another definition though.

Other than that, I'm not aware of a language feature that will lock away your function in such a way which prevents it from being overloaded and still able to be invoked through a pointer/reference to the child class.

Good luck!

OJ.
  • 28,944
  • 5
  • 56
  • 71
  • 1
    but then we cannot call that method from other classes. ? – anshulkatta Jul 01 '14 at 08:35
  • 11
    Note that there is a `final` specifier added with C++11: http://stackoverflow.com/a/16906116/1025391 – moooeeeep Jun 11 '15 at 14:56
  • 2
    @moooeeeep final does not work in this case: `struct foo { void bar() final; };` is not legal C++ – Jean-Michaël Celerier Aug 03 '18 at 12:34
  • 1
    @Jean-MichaëlCelerier Yes, you need to make it virtual too for this to work. – moooeeeep Aug 03 '18 at 19:25
  • @moooeeeep well, yes, but the question is explicitely about non virtual functions. Sometimes you don't want (if for instance you need compatibility with a C API) virtuals. – Jean-Michaël Celerier Aug 04 '18 at 11:22
  • 1
    @Jean-MichaëlCelerier I see, but sometimes you can do it. That's why I added the note. – moooeeeep Aug 04 '18 at 18:41
  • 1
    seems silly but I think the only way to do this is make it `virtual` in the base class, also `final` as that will prevent both an override and a shadow. It seems silly to make it virtual when there is no intent to allow it in a subclass. a lacking C++ feature. – johnbakers Nov 28 '19 at 10:19
8

Sounds like what you're looking for is the equivalent of the Java language final keyword that prevents a method from being overridden by a subclass.

As others here have suggested, you really can't prevent this. Also, it seems that this is a rather frequently asked question.

Community
  • 1
  • 1
Danny Whitt
  • 1,151
  • 13
  • 21
  • 5
    The `final` keyword is introduced by C++11 (http://en.cppreference.com/w/cpp/language/final). Also have a look at my answer here (http://stackoverflow.com/a/16896559/1025391) for another example. – moooeeeep Jun 03 '13 at 12:20
  • Nice, I didn't know that. Thanks for the references! – Danny Whitt Jun 11 '13 at 14:42
3

(a) I dont think making function private is the solution because that will just hide the base class function from the derived class.The derived class can always define a new function with the same signature. (b) Making the function non virtual is also not a complete solution because, if the derived class redefines the same function , one can always call the derived class function by compile time binding i.e obj.someFunction() where obj is an instance of the derived class.

I dont think there is a way of doing this.Also,i would like to know the reason for your decision to prohibit derived classes from overriding base class functions.

2

I guess what the compiler warns you about is hiding !! Is it actually being overridden ?

compiler might give you a warning, but at runtime, the parent class method will be called if the pointer is of type parent class, regardless of the actual type of the object it points to.

This is interesting. Try making a small standalone test program for your compiler.

RuntimeException
  • 1,593
  • 2
  • 22
  • 31
2

a compile time warning about hiding non-virtual inherited function X.

change your compiler settings to make it a error instead of warning.

csmba
  • 4,053
  • 3
  • 32
  • 42
1

For clarification, most of you misunderstood his question. He is not asking about "overriding" a method, he is asking whether there is a way to prevent "hiding" or not. And the simple answer is that "there is none!".

Here's his example once again

Parent class defines a function:

int foo() { return 1; }

Child class, inheriting the Parent defines the same function AGAIN (not overriding):

int foo() { return 2; }

You can do this on all programming languages. There is nothing to prevent this code from compiling (except a setting on the compiler). The best you'll get is a warning that you are hiding the parent's method. If you call the child class and invoke the foo method, you'll get 2. You have practically broken the code.

This is what he is asking.

LPL
  • 16,827
  • 6
  • 51
  • 95
0

In your example, no function is overridden. It is instead hidden (it is a kind of degenerated case of overloading). The error is in the Child class code. As csmba suggested, all you can do is changing your compiler settings (if possible) ; it should be fine as long as you don't use a third party library that hides its own functions.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
0

If you address the child class as a type of its parent, then a non-virtual function will call the parent class's version.

ie:

Parent* obj = new Child();
Ryan Fox
  • 10,103
  • 5
  • 38
  • 48
0

Unless you make the method virtual, the child class cannot override it. If you want to keep child classes from calling it, make it private.

So by default C++ does what you want.

Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
0

Technically u can prevent virtual functions to be be overridden. But you will never ever been able to change or add more. That is not help full. Better to use comment in front of function as faq lite suggests.

0

Trying to prevent someone from using the same name as your function in a subclass isn't much different than trying to prevent someone from using the same global function name as you have declared in a linked library.

You can only hope that users that mean to use your code, and not others', will be careful with how they reference your code and that they use the right pointer type or use a fully qualified scope.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
-1

I was searching for same and yesterday came to this [rather old] question.

Today I found a neat c++11 keyword : final . I thought it may be useful for next readers.

http://en.cppreference.com/w/cpp/language/final

Abhay Bhave
  • 44
  • 1
  • 8
  • 2
    This answer adds nothing other answers have not already stated; furthermore, `final` can only be used for `virtual` methods. – rdb Apr 25 '21 at 14:33
-2

C++ methods are private and un-overridable by default.

  • You cannot override a private method
  • You cannot override a non-virtual method

Are you perhaps referring to overloading?

Frank Krueger
  • 69,552
  • 46
  • 163
  • 208