20

How can I enforce that a base class method is not being overridden by a derived class?

Cœur
  • 37,241
  • 25
  • 195
  • 267
sriks
  • 563
  • 2
  • 6
  • 17
  • 5
    Don't make it virtual in the base class? Then it can't be overridden, only overloaded. There is no direct equivalent to Java's `final` methods, if that's the question. – Steve Jessop Dec 16 '10 at 21:51
  • so without using a virtual key word we cannot make it, so how did they implemented in JAVA then – sriks Dec 17 '10 at 13:15
  • in Java, marking a method `final` forbids subclasses from implementing that method, and the compiler and/or byte code verifier will enforce this. In C++, there's no way to forbid it, it's just that by definition of "override", only virtual functions can be "overridden". – Steve Jessop Dec 17 '10 at 14:33
  • 4
    Note that there is a `final` specifier added with C++11: http://stackoverflow.com/a/16896559/1025391 – moooeeeep Jun 03 '13 at 12:37

6 Answers6

38

If you are able to use the final specifier from C++11 you can prevent derived classes from override that method. (Microsoft compilers appear to support the similar sealed with similar semantics.)

Here's an example:

#include <iostream>

struct base {
    // To derived class' developers: Thou shalt not override this method
    virtual void work() final {
        pre_work();
        do_work();
        post_work();
    }
    virtual void pre_work() {};
    virtual void do_work() = 0;
    virtual void post_work() {};
};

struct derived : public base {
    // this should trigger an error:
    void work() {
        std::cout << "doing derived work\n";
    }
    void do_work() {
        std::cout << "doing something really very important\n";
    }
};

int main() {
    derived d;
    d.work();
    base& b = d;
    b.work();
}

Here's what I get when I try to compile it:

$ g++ test.cc -std=c++11
test.cc:17:14: error: virtual function ‘virtual void derived::work()’
test.cc:5:22: error: overriding final function ‘virtual void base::work()’
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • 4
    Question: Why should I declare "work()" as "virtual" when I don't want that it is overridden in derived classes - why not just mark it as final? – Sonic78 Dec 11 '17 at 09:13
  • 5
    @Sonic78 Good question! In real world code, you might have another base class to `base`, that provides a virtual function that you want to prevent to be overridden in classes deriving from your intermediate base. – moooeeeep Dec 12 '17 at 07:55
19

If you make the method non-virtual, derived classes cannot override the method. However, in C++03 a class cannot override a method from a base class, and also prevent further derived classes from overriding the same method. Once the method is virtual, it stays virtual.

plasmacel
  • 8,183
  • 7
  • 53
  • 101
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
3

Don't make it virtual.

This won't prevent deriving from your class and hiding the function (by providing another member function with the same name). However, if your class is not meant to be derived anyway (no virtual destructor, no virtual member functions), that shouldn't be an issue.

icecrime
  • 74,451
  • 13
  • 99
  • 111
1

well if you want to keep it public, dont declare it virtual.

EDIT: Srikanth commented wondering about overriding a private member function in a derived class.

class A
{
public:
    virtual ~A(){};
    void test()
    {
        foo();
    };
private:
    virtual void foo()
    {
        std::cout << "A";   
    };
};


class B : public A
{
public:
    virtual void foo()
    {
        std::cout << "B";   
    };
};


void test()
{
    B b;
    A& a = b;

    a.test(); // this calls the derived B::foo()

    return 0;
}`
Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
0

well as far as i know you can't do that on c++, you can try to declare it as private. . find more info on this link http://en.allexperts.com/q/C-1040/prevent-overriding-functions-derived.htm

Luponk
  • 21
  • 3
-1

Short answer: there is no need for that. Long answer you can do some twists, but is it worth it?

Gene Bushuyev
  • 5,512
  • 20
  • 19