Safely override C++ virtual functions

穿精又带淫゛_ 提交于 2019-11-27 10:32:52
Gunther Piez

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;
};

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.

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.

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.

In MSVC++ you can use keyword override

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

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

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. */ }

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!