使用最终类说明符时,最终函数说明符是否冗余?

Is the final function specifier redundant when using the final class specifier?

本文关键字:说明符 是否 冗余 函数      更新时间:2023-10-16

当类已经final时,是否有任何理由将函数指定为final?还是多余的?

class B
{
public:
virtual void f();
};
class D final : public B
{
public:
virtual void f() final; // Redundant final?
};

说:从使整个类final开始,只有在需要从类派生和/或覆盖特定函数时才切换到使单个函数final,这是一个很好的经验法则吗?

这绝对是多余的,因为将整个类标记为final使得无法从该类派生,因此无法覆盖任何内容。

9 类 [类]

  1. 如果一个类被标记为类virt-specifier final,并且它在基子句中显示为基类型说明符 (第10条),程序格式不正确。

因此,编译器甚至不会费心检查从类派生final类是否真的试图覆盖任何东西。

不,它不是多余的,因为final应用于类和方法时意味着不同的东西。

  • final应用于一个类时,这意味着该类可能不会出现在另一个类的基本说明符列表中(即你不能从它继承)

  • final应用于成员函数时,这意味着该函数在祖先类中必须是虚拟的,并进一步指定它不能在后代类中被重写。

关键的区别在于,成员函数final你必须重写祖先类中的虚拟方法 - 否则,编译器会抛出错误。 当应用于成员函数时,final基本上是override关键字的扩展。

final应用于方法对于捕获细微的 bug 非常有帮助,如果只在类上指定final,则不会捕获这些错误。

示例 1:如果函数名称拼写错误,或者没有完美地重现参数列表,则该函数实际上不会覆盖基函数,并且在您认为要调用它时不会调用该函数。 但是,如果您指定该函数final(或override),编译器将检测到您没有成功覆盖基函数,并会抛出错误。 如果您只指定了类是final,编译器不会关心您的函数实际上没有覆盖虚函数,也不会抛出错误。

示例 2:如果您指定final成员函数并且基类中的函数签名发生更改(例如,有人在您测试和签入代码后对基类进行了更改),编译器将帮助指出基函数不再被您的函数覆盖。