“final”的配方:省略“virtual”?

发布于 2024-12-06 10:38:55 字数 1042 浏览 0 评论 0 原文

如果我编写final(对成员函数),就不应该编写virtual,这是否是一个有效的秘诀?

在基类中, final 方法毫无意义:

struct Driver {
    virtual void print();
};

如果将 final 添加到 print() 中,这首先就会违背多态性的原因。所以这将是无用的(尽管可能)。

当我从此类派生时,我可以检测到 final 错误,但只能没有 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
};

附加的 KeyboardDriver::prynt 的 >final 是合法的。因为final只要求成员函数是virtual——编译器会让这个通过(FDIS 9.2p9)。

但是,当我省略virtual时,拼写错误使该函数成为非虚拟函数——它不会覆盖任何内容,即没有虚拟函数。因此,没有virtualfinal在这方面与override具有相同的目的。

更新:我的分析正确吗?没有 virtualfinal 功能是否包括 override 之一?

Is it a valid recipe to say that if I write final (to a member function) one should 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请爱~陌生人 2024-12-13 10:38:55

你的分析是正确的。不将 final 成员标记为 virtual 可以避免声明新的、不可重写的成员并捕获错误。但是,由于这就是override的目的,因此使用final override可能会更简单;那么该成员是否被标记为virtual 根本不重要。

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.

只是我以为 2024-12-13 10:38:55

这不是 final 的用途。您正在寻找的是覆盖

struct Base { 
  virtual void print();
};

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

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

如果您将某个函数标记为override,但实际上它没有,则会出现错误。与您的最终函数相结合,您可以获得编译器检查安全性的所有便利,并且在编码标准需要时可以清楚地显式标记函数virtual

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

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;
};
懒的傷心 2024-12-13 10:38:55

我不认为这是一个错误,它只是一个不能重载的虚函数。如果该函数在父类中声明为 virtual ,也会发生同样的情况,因为 virtual 声明是继承的。禁止它是没有意义的。

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.

听风念你 2024-12-13 10:38:55

我的分析正确吗?没有 virtual 的 Final 的功能是否包括 override 的功能?

不。这是编译器错误的原因:

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

因为 final 只允许在虚拟函数上使用。编译器会抱怨,因为您在非虚拟函数上使用了它。

这行代码在语法上没有任何错误:

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

它可能不是您想要的,但这是合法的(甚至是有意义的,取决于具体情况)代码。

您遇到的问题是由于想要执行此操作:

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

省略 virtual 在技术上是合法的。但就我个人而言,我一直觉得这种形式很糟糕。您将重要信息(哪些函数被覆盖)放入另一个类中。我认为允许它编译是一个错误。

如果您想避免此问题,请在所有个虚拟函数上显式声明virtual,并在您想要创建虚拟函数的地方使用override新功能。那么,这将无法正确编译。

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

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;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文