开发者

Recipe for `final`: omit `virtual`?

Is it a valid recipe to say that if I write final (to a member function) one shoul开发者_StackOverflow社区d not write virtual?

In a base class, final methods would make no sense:

struct Driver {
    virtual void print();
};

If one would add final to print() this would defy the reason for polymorphism in the first place. So that would be useless (though possible).

When I derive from this class I can detect errors with final, but only without virtual:

struct KeyboardDriver : public Driver {
    virtual void prynt() final;    // Oops: typo, but compiler-ok
};

struct MouseDriver : public Driver {
    void prynt() final;    // Error: Hooray, compiler found my typo
};

The additional final for KeyboardDriver::prynt was legal. Because final only requires the member function to be virtual -- the compiler lets this pass (FDIS 9.2p9).

But when I leave out the virtual the typo makes this function non-virtual -- it overrides nothing, i.e. no virtual function. Therefore final without virtual serves the same purpose to this respect as override does.

Update: Is my analysis correct? Does the functionality of final without virtual include that one of override?


Your analysis is correct. Not marking a final member as virtual avoids declaring a new, non-overriden member and catches mistakes. However, since that's the purpose of override, it may be simpler to just use final override; then whether the member is marked virtual or not won't matter at all.


That is not what final is for. What you are looking for is override.

struct Base { 
  virtual void print();
};

struct Derived : Base {
  void prynt() override; //compiler error
};

struct Good : Base {
  void print() override; //no compiler error
};

If you mark a function as override when it does not, then you get an error. Combined with your final function, you get all the comforts of compiler checked safety, with the clarity of explicitly marking functions virtual when coding standards demand it.

struct Best : Base {
  virtual void print() final override;
};


I do not think it is an error, it's just a virtual function that can not be overloaded. Same thing that would happen if the function were declared virtual in a parent class, since virtual declarations are inherited. It would make no sense to forbid it.


Is my analysis correct? Does the functionality of final without virtual include that one of override?

No. The reason that this was a compiler error:

void prynt() final;    // Error: Hooray, compiler found my typo

Is because final is only allowed on virtual functions. The compiler is complaining because you used it on a function that isn't virtual.

There is nothing syntactically wrong about this line:

virtual void prynt() final;    // Oops: typo, but compiler-ok

It may not be what you want, but this is legitimate (and even meaningful, depending on the circumstances) code.

The problem you are encountering is due to wanting to do this:

struct Driver {
    virtual void print();
};
struct MouseDriver : public Driver {
    void print();
};

Omitting the virtual is technically legal. But personally, I've always felt that it was bad form. You're putting vital information (which functions are overridden) into another class. I think it was a mistake to even allow this to compile.

If you want to avoid this problem, then explicitly state virtual on all virtual functions, and use override in the places where you mean to create a new function. Then, this will fail to compile correctly.

struct Driver {
    virtual void print();
};
struct MouseDriver : public Driver {
    virtual void print() override;
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜