105

I have a base class with a virtual function and I want to override that function in a derived class. Is there some way to make the compiler check if the function I declared in the derived class actually overrides a function in the base class? I would like to add some macro or something that ensures that I didn't accidentally declare a new function, instead of overriding the old one.

Take this example:

class parent {
public:
  virtual void handle_event(int something) const {
    // boring default code
  }
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1);
}

Here parent::handle_event() is called instead of child::handle_event(), because the child's method misses the const declaration and therefore declares a new method. This could also be a typo in the function name or some minor difference in the parameters types. It can also easily happen if the interface of the base class changes and somewhere some derived class wasn't updated to reflect the change.

Is there some way to avoid this problem, can I somehow tell the compiler or some other tool to check this for me? Any helpful compiler flags (preferably for g++)? How do you avoid these problems?

sth
  • 222,467
  • 53
  • 283
  • 367
  • 2
    Great question, I have been trying to figure out why my child class function doesn;t get called since an hour now! – Akash Mankar Dec 16 '14 at 00:52

10 Answers10

93

Since g++ 4.7 it does understand the new C++11 override keyword:

class child : public parent {
    public:
      // force handle_event to override a existing function in parent
      // error out if the function with the correct signature does not exist
      void handle_event(int something) override;
};
魔大农
  • 100
  • 8
Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • @hirschhornsalz: I found that when you implement the handle_event function and you append override at the end of the function implementation, g++ gives an error; if you provide an inline function implementation in the class declaration following the override keyword, everything is fine. Why? – h9uest Jan 04 '15 at 16:05
  • 4
    @h9uest `override` must be used in the definition. An inline implementation is both definition and implementation, so thats ok. – Gunther Piez Jan 05 '15 at 10:34
  • @hirschhornsalz yeah I got the same error msg by g++. A side note, though: both you and g++ error msg used the term "class definition" - shouldn't we use "declaration"({declaration, definition} pair)? You made yourself clear in this particular context by saying "definition & implementation", but I just wonder why the c++ community suddenly decides to change terms on classes? – h9uest Jan 05 '15 at 10:45
20

Something like C#'s override keyword is not part of C++.

In gcc, -Woverloaded-virtual warns against hiding a base class virtual function with a function of the same name but a sufficiently different signature that it doesn't override it. It won't, though, protect you against failing to override a function due to mis-spelling the function name itself.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 2
    It is if you happen to be using Visual C++ – Steve Rowe Feb 01 '09 at 16:45
  • 4
    Using Visual C++ does not make `override` a keyword in C++; it might mean that you are using something that can compile some invalid C++ source code, though. ;) – CB Bailey Feb 01 '09 at 16:56
  • 3
    The fact that override is invalid C++ means the standard is wrong, and not Visual C++ – Jon Jun 04 '10 at 06:05
  • @Jon: I didn't say that Visual C++ was wrong, I said that it might compile code that isn't C++. Visual C++ supports extensions. `override` is a valid identifier in C++, but even if it wasn't I'm not sure how that would make the standard wrong. – CB Bailey Jun 04 '10 at 06:33
  • @Charles: What I'm trying to say is that standard C++ is lacking. `override` is such a useful and easy to implement concept, that the standard should have it, and people using VC++ without needing to port to other compilers should use it. – Jon Jun 04 '10 at 13:00
  • 2
    @Jon: OK, now I see what you were driving at. Personally I could take or leave C# style `override` functionality; I've rarely had problems with failed overrides and they've been relatively easy to diagnose and fix. One think I won't agree with is that VC++ users should use it. I'd prefer that C++ look like C++ on all platforms even if one particular project doesn't need to be portable. It's worth noting that C++0x will have `[[base_check]]`, `[[override]]` and `[[hiding]]` attributes so you can opt in to override checking if desired. – CB Bailey Jun 04 '10 at 22:35
  • 5
    Funnily enough, a couple of years after the comment *using VC++ does not make `override` a keyword* it seems it *did*. Well, not a proper keyword but a special identifier in C++11. Microsoft pushed hard enough to make a special case of this and to follow the general format for attributes and `override` made it into the standard :) – David Rodríguez - dribeas Jan 26 '12 at 13:10
  • @david in the end, override went in as a full-blown keyword rather than an attribute. – David Heffernan Apr 05 '12 at 23:13
  • @DavidHeffernan: `override` isn't a keyword in c++, it's an identifier with a special meaning in some contexts. – CB Bailey Apr 05 '12 at 23:17
  • @charles ok, I don't know the nuances. I just read Herb's post about attributes. Thanks. – David Heffernan Apr 05 '12 at 23:26
  • @DavidHeffernan: Charles is right, the distinction is that you can use `override` as a identifier everywhere else (which you could not if the identifier was a full blown keyword) – David Rodríguez - dribeas Apr 06 '12 at 01:29
  • Makes you wonder why it was ever considered as an attribute if it could be done this way. – David Heffernan Apr 06 '12 at 07:17
18

As far as I know, can't you just make it abstract?

class parent {
public:
  virtual void handle_event(int something) const = 0 {
    // boring default code
  }
};

I thought I read on www.parashift.com that you can actually implement an abstract method. Which makes sense to me personally, the only thing it does is force subclasses to implement it, no one said anything about it not being allowed to have an implementation itself.

Ray Hidayat
  • 16,055
  • 4
  • 37
  • 43
  • Only now have I realized this works on more than just destructors! Great find. – strager Jan 31 '09 at 00:20
  • 1
    There are a couple potential drawbacks to this: 1) the other thing that marking one or more methods as abstract does is make the base class non-instantiable, which may be a problem if that's not part of the intended use of the class. 2) the base class might not be yours to modify in the first place. – Michael Burr Jan 31 '09 at 06:58
  • 3
    I agree with Michael Burr. Making the base-class abstract isn't part of the question. It's perfectly reasonable to have a base class with functionality in a virtual method, that you want a derived class to override. And it's just as reasonable to want to protect against another programmer renaming the function in the base class, and causing your derived class to no longer override it. The Microsoft "override" extension is invaluable in this case. I'd love to see it added to the standard, because unfortunately there's no good way to do this without it. – Brian Jan 10 '12 at 23:30
  • This also prevents the base method (say `BaseClass::method()`) to be called in the derived implementation (say `DerivedClass::method()`), e.g. for a default value. – Narcolessico Jan 05 '18 at 09:01
11

In MSVC, you can use the CLR override keyword even if you're not compiling for CLR.

In g++, there's no direct way of enforcing that in all cases; other people have given good answers on how to catch signature differences using -Woverloaded-virtual. In a future version, someone might add syntax like __attribute__ ((override)) or the equivalent using the C++0x syntax.

Doug
  • 8,780
  • 2
  • 27
  • 37
9

In MSVC++ you can use keyword override

class child : public parent {
public:
  virtual void handle_event(int something) <b>override</b> {
    // new exciting code
  }
};

override works both for native and CLR code in MSVC++.

Zoe
  • 27,060
  • 21
  • 118
  • 148
bobobobo
  • 64,917
  • 62
  • 258
  • 363
5

Make the function abstract, so that derived classes have no other choice than to override it.

@Ray Your code is invalid.

class parent {
public:
  virtual void handle_event(int something) const = 0 {
    // boring default code
  }
};

Abstract functions cannot have bodies defined inline. It must be modified to become

class parent {
public:
  virtual void handle_event(int something) const = 0;
};

void parent::handle_event( int something ) { /* do w/e you want here. */ }
Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32
3

I would suggest a slight change in your logic. It may or may not work, depending on what you need to accomplish.

handle_event() can still do the "boring default code" but instead of being virtual, at the point where you want it to do the "new exciting code" have the base class call an abstract method (i.e. must-be-overridden) method that will be supplied by your descendant class.

EDIT: And if you later decide that some of your descendant classes do not need to provide "new exciting code" then you can change the abstract to virtual and supply an empty base class implementation of that "inserted" functionality.

JMD
  • 7,331
  • 3
  • 29
  • 39
2

Your compiler may have a warning that it can generate if a base class function becomes hidden. If it does, enable it. That will catch const clashes and differences in parameter lists. Unfortunately this won't uncover a spelling error.

For example, this is warning C4263 in Microsoft Visual C++.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

C++11 override keyword when used with the function declaration inside the derived class, it forces the compiler to check that the declared function is actually overriding some base class function. Otherwise, the compiler will throw an error.

Hence you can use override specifier to ensure dynamic polymorphism (function overriding).

class derived: public base{
public:
  virtual void func_name(int var_name) override {
    // statement
  }
};
Adarsh Kumar
  • 467
  • 6
  • 11
0
class MyClass {
public:
 
  MyClass() {}
  virtual uint32_t someFunction(bool param = false) {
    if (param) {
      std::cout << "This is an example virtual function with default code" << std::endl;
    }
    return 1100;  //just for return something
  };

 
  • then you can override the function as you need
class MyClass2 : public MyClass  {
public:
  MyClass2();
  uint32_t someFunction(bool param) override;
};


uint32_t MyClass2::someFunction(bool verbose) {
  std::cout << "This is new implementation for virtual method " << std::endl;

}