显式重写虚函数

6
我刚刚发现C++/CLI有一个关键字,在标准的C++中是不存在的(据我所知):override
我不太了解C++/CLI,请问有人能解释一下它的目的是什么,以及是否应该将其作为C++的一个可取特性添加进去?

你没有说你想要的关键字是什么。是“explicit”吗?如果是,它在标准C++中。 - Wes Hardaker
3
@Wes Hardaker,实际上我说的是“override”关键字。 - kunigami
4个回答

12

override 是来自于微软的专门用于 C++/CLI 和 Visual C++ 实现的一个特殊关键字扩展。它类似于 Java 中的 @Override 注解或者 C# 中的 override,并且提供了更好的编译时检查机制,以防您没有正确覆盖您想要覆盖的内容。

来自第一个链接:

override 表示托管类型的成员必须覆盖基类或者基接口中的成员。如果没有成员需要覆盖,编译器会生成一个错误。

在编译为本机目标(不带 /clr)时,override 也是有效的。更多信息请参见 Override Specifiers and Native Compilations。

override 是一种上下文敏感的关键字。更多信息请参见 Context-Sensitive Keywords。

从 C++11 标准开始,override 说明符现在成为了一个标准化的关键字。然而,支持仍然有限。根据这个来自 Apache StdCxx 的页面,GCC 4.7+、Intel C++ 12.0+ 和 Visual C++ 2012(在 Visual C++ 2005 中具有预标准化支持)都支持 override


2

它有两种方式帮助编译器捕获您的错误:

  1. 如果您在类中使用override声明函数,但是基类没有该函数,则编译器可以告诉您您没有覆盖您认为的内容。如果没有override,则编译器将无法识别您的错误 - 它只会假定您打算引入一个新函数。

  2. 如果您在派生类中有一个函数(没有override),然后在基类中将同一函数声明为虚函数,则编译器可以告诉您基类中的更改已经影响了派生类中原始声明的含义。派生类将需要使用override,或者您需要更改其中一个函数的签名。

这个特性已经被添加到C++0x中了。


1
我不认为#2是正确的。您可以在不实际使用“override”关键字的情况下轻松覆盖函数。如果这种情况发生变化,许多现有代码将会出现问题。 - Ben Voigt

0

C++/CLI 中的 override 关键字来自 .Net 而不是 C++ 本身。由于已经解释了 override,您需要知道替代方案。如果您不“override”它,则可能希望将其“new”。通过将其“new”,您不会在子类中覆盖父类成员,而是创建一个具有相同名称的新成员。当您使用基类指针并将其指向派生类对象时,new 和 override 关键字仅在使用时有所不同。

因此,如果您使用基类指针并指向派生类对象:

If you call an "override"n member:
      the derived class member is called
if you call the "new"ed member:
      the base class member is called.

0

这里开始:

如果在父类中使用 virtual 关键字标记属性或方法,那么在从它派生一个类时,您可以忽略该方法或属性而不实现它。但是,如果您决定实现该属性或方法,则必须指示您正在提供该属性或方法的新版本。提供属性或方法的新版本称为覆盖。

当覆盖属性或方法时,您必须通过将 override 关键字写在其右侧来指示此操作。

现在请点击链接查看一些示例。


这解释了override关键字的机制,但并没有解释为什么引入它。 - Martin York
像Rob的#2一样,这是不正确的。匹配基类中声明为虚函数的函数签名就足以覆盖函数,override关键字可以省略,函数仍然会被覆盖。新的关键字不能强制成为必需品,否则将破坏大量现有代码。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接