C++ override specifier (C++ override 说明符)

C++ override specifier [C++ override 说明符]

  • 1. C++ override specifier
  • 2. C++ override 说明符
  • 3. Compiler Error C2723
  • References

在派生类中用 override 修饰符定义虚函数时,编译器会验证直接或间接基类是否包含签名相同的虚函数。如果不包含,就生成一个错误消息。

1. C++ override specifier

C++ documentation (C++ 文档)
https://learn.microsoft.com/en-us/cpp/cpp/
https://learn.microsoft.com/zh-cn/cpp/cpp/

override specifier (override 说明符)
https://learn.microsoft.com/en-us/cpp/cpp/override-specifier
https://learn.microsoft.com/zh-cn/cpp/cpp/override-specifier

You can use the override specifier to designate member functions that override a virtual function in a base class.
可以使用 override 说明符来指定覆盖基类中的虚成员函数。

override is context-sensitive and has special meaning only when it’s used after a member function declaration; otherwise, it’s not a reserved keyword.
override 是上下文相关的,只有在成员函数声明后使用时才具有特殊含义;否则,它不是保留关键字。

Use override to help prevent inadvertent inheritance behavior in your code. The following example shows where, without using override, the member function behavior of the derived class may not have been intended. The compiler doesn’t emit any errors for this code.
使用 override 有助于防止你的代码中出现意外的继承行为。以下示例演示在未使用 override 的情况下,可能不打算使用派生类的成员函数行为。编译器不会发出此代码的任何错误。

class BaseClass {
	virtual void funcA();
	virtual void funcB() const;
	virtual void funcC(int = 0);
	void funcD();
};

class DerivedClass : public BaseClass {
	virtual void funcA();  // Works as intended

	// DerivedClass::funcB() is non-const, so it does not override BaseClass::funcB() const 
	// and it is a new member function
	virtual void funcB();

	// DerivedClass::funcC(double) has a different parameter type than BaseClass::funcC(int), 
	// so DerivedClass::funcC(double) is a new member function
	virtual void funcC(double = 0.0);
};

When you use override, the compiler generates errors instead of silently creating new member functions.
当使用 override 时,编译器会生成错误,而不会在不提示的情况下创建新的成员函数。

class BaseClass {
	virtual void funcA();
	virtual void funcB() const;
	virtual void funcC(int = 0);
	void funcD();
};

class DerivedClass : public BaseClass {
	virtual void funcA() override; // ok

	// Compiler error: DerivedClass::funcB() does not override BaseClass::funcB() const
	virtual void funcB() override;

	// Compiler error: DerivedClass::funcC(double) does not override BaseClass::funcC(int)
	virtual void funcC(double = 0.0) override;

	// Compiler error: DerivedClass::funcD() does not override the non-virtual BaseClass::funcD()
	void funcD() override;
};

To specify that functions cannot be overridden and that classes cannot be inherited, use the final specifier.
若要指定不能重写函数且不能继承类,请使用 final 说明符。

2. C++ override 说明符

派生类如果定义了一个函数与基类中虚函数的名字相同但是形参列表不同,这仍然是合法的行为。编译器将认为新定义的这个函数与基类中原有的函数是相互独立的,派生类的函数并没有覆盖掉基类中的版本。就实际的编程习惯而言,这种声明往往意味着发生了错误,因为我们可能原本希望派生类能覆盖掉基类中的虚函数,但是一不小心把形参列表弄错了。

在 C++11 新标准中我们可以使用 override 修饰符来说明派生类中的虚函数。如果我们使用 override 标记了某个函数,但该函数并没有覆盖已存在的虚函数,此时编译器将报错。

struct B {
	virtual void f1(int) const;
	virtual void f2();
	void f3();
};

struct D1 : B {
	void f1(int) const override;  // 正确:f1 与基类中的 f1 匹配
	void f2(int) override;  // 错误:B 没有 void f2(int) 形式的函数
	void f3() override;  // 错误:f3 不是虚函数
	void f4() override;  // 错误:B 没有名为 f4 的函数
};

D1 中,f1override 说明符是正确的,因为基类和派生类中的 f1 都是 const 成员,并且它们都接受一个 int 并返回 void,所以 D1 中的 f1 正确地覆盖了它从 B 中继承而来的虚函数。

D1f2 的声明与 Bf2 的声明不匹配,显然 B 中定义的 f2 不接受任何参数而 D1f2 接受一个 int。因为这两个声明不匹配,所以 D1f2 不能覆盖 Bf2,它是一个新函数,仅仅是名字恰好与原来的函数一样而已。因为我们使用 override 所表达的意思是我们希望能覆盖基类中的虚函数而实际上并未做到,所以编译器会报错。

因为只有虚函数才能被覆盖,所以编译器会拒绝 D1f3。该函数不是 B 中的虚函数,因此它不能被覆盖。类似的,f4 的声明也会发生错误,因为 B 中根本就没有名为 f4 的函数。

3. Compiler Error C2723

‘function’ : ‘specifier’ specifier illegal on function definition

error C2723: '***': 'override' specifier illegal on function definition

'override' specifier is not allowed outside a class definition

The specifier cannot appear with a function definition outside of a class declaration. The virtual specifier can be specified only on a member function declaration within a class declaration.
说明符不能与类声明外部的函数定义同时出现,仅能对类声明内的成员函数声明指定 virtual 说明符。

References

[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] C++ final specifier 禁止派生类和禁止重写函数, https://blog.csdn.net/chengyq116/article/details/104477726

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/776522.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS position属性之relative和absolute

目录 1 参考文章2 五个属性值3 position:static4 position:relative(相对)5 position:absolute(绝对) 1 参考文章 https://blog.csdn.net/lalala_dxf/article/details/123566909 https://blog.csdn.net/WangMinGirl/article/deta…

番外篇 | 手把手教你如何去更换YOLOv5的检测头为IDetect | 源于RCS-YOLO

前言:Hello大家好,我是小哥谈。凭借速度和准确性之间的出色平衡,YOLO框架已成为最有效的目标检测算法之一。然而,在脑肿瘤检测中很少研究使用YOLO网络的性能。对此本文提出了一种基于RCS-YOLO的重新参数化卷积的新型YOLO架构。与YOLOv7相比,RCS-YOLO的精度提高了2.6%,推理…

MWC上海展 | 创新微MinewSemi携ME54系列新品亮相Nordic展台

6月28日, 2024MWC上海圆满落幕,此次盛会吸引了来自全球124个国家及地区的近40,000名与会者。本届大会以“未来先行(Future First)”为主题,聚焦“超越5G”“人工智能经济”“数智制造”三大子主题,探索讨论…

苹果电脑清理app垃圾高效清理,无需专业知识

在我们的日常使用中,苹果电脑以其优雅的设计和强大的功能赢得了广泛的喜爱。然而,即便是最高效的设备,也无法免俗地积累各种不必要的文件和垃圾,特别是app垃圾。所以,苹果电脑清理app垃圾高效清理,对于大多…

数据的存储方式——大小端序

大小端存储的故事源自于《格列佛游记》(Gullivers Travels),这是爱尔兰作家乔纳森斯威夫特(Jonathan Swift)于1726年所著的一部讽刺小说。在其中,主人公格列佛(Lemuel Gulliver)游历…

三相感应电机的建模仿真(2)基于ABC相坐标系S-Fun的仿真模型

1. 概述 2. 三相感应电动机状态方程式 3. 基于S-Function的仿真模型建立 4. 瞬态分析实例 5. 总结 6. 参考文献 1. 概述 前面建立的三相感应电机在ABC相坐标系下的数学模型是一组周期性变系数微分方程(其电感矩阵是转子位置角的函数,转子位置角随时…

【Python】基于KMeans的航空公司客户数据聚类分析

💐大家好!我是码银~,欢迎关注💐: CSDN:码银 公众号:码银学编程 实验目的和要求 会用Python创建Kmeans聚类分析模型使用KMeans模型对航空公司客户价值进行聚类分析会对聚类结果进行分析评价 实…

面向物联网行业的异常监控追踪技术解决方案:技术革新与运维保障

在现代高度数字化和互联的环境中,物联网技术已经深入到我们生活的方方面面。特别是在家庭和工业环境中,物联网系列通讯作为连接各类设备的关键枢纽,其稳定性和可靠性显得尤为重要。本文将介绍一种创新的监控系统,旨在实时跟踪和分…

用Python轻松转换PDF为CSV

数据的可访问性和可操作性是数据管理的核心要素。PDF格式因其跨平台兼容性和版面固定性,在文档分享和打印方面表现出色,尤其适用于报表、调查结果等数据的存储。然而,PDF的非结构化特性限制了其在数据分析领域的应用。相比之下,CS…

DFS之剪枝与优化——AcWing 165. 小猫爬山

DFS之剪枝与优化 定义 DFS之剪枝与优化指的是在执行深度优先搜索(DFS, Depth-First Search)时,采取的一系列策略来减少搜索空间,避免无效计算,从而加速找到问题的解。剪枝是指在搜索过程中,当遇到某些条件不符合解的要求或者可以…

Day05-02-Jenkins-pipeline

Day05-02-Jenkins-pipeline 1. Jenkins-Pipeline概述1) pipeline? 2. pipeline格式3. 小试牛刀4. Java上线的项目4.1 流程汇总4.2 根据流程书写pipeline架构4.3 分步实现1)拉取代码2)检查,编译,部署 4.4 完整pipeline代码 5. 根据tag标签拉取代码(了解自…

FreeBSD@ThinkPad x250因电池耗尽关机后无法启动的问题存档

好几次碰到电池耗尽FreeBSD关机,再启动,网络通了之后到了该出Xwindows窗体的时候,屏幕灭掉,网络不通,只有风扇在响,启动失败。关键是长按开关键后再次开机,还是启动失败。 偶尔有时候重启到单人…

温州网站建设方案及报价

随着互联网的发展,网站建设已经成为企业推广和营销的重要手段。温州作为中国经济发达地区之一,各行各业企业纷纷意识到网站建设的重要性,纷纷加大网站建设工作的投入。那么,温州网站建设方案及报价是怎样的呢?下面我们…

深入理解C# log4Net日志框架:功能、使用方法与性能优势

文章目录 1、log4Net的主要特性2、log4Net框架详解配置日志级别 3、log4Net的使用示例4、性能优化与对比5、总结与展望 在软件开发过程中,日志记录是一个不可或缺的功能。它可以帮助开发者追踪错误、监控应用程序性能,以及进行调试。在C#生态系统中&…

C#运算符重载

1、运算符重载 运算符重载是指重定义C#内置的运算符。 程序员也可以使用用户自定义类型的运算符。重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样,重载运算符有返回类型和参数列表。 2、在Box类中定义…

C++ volatile 关键字

C volatile (只有release下才会生效) 1、告诉编译器volatile修饰的变量不要进行指令顺序的优化,以保证代码编写者的真实意图; int a 0;int b 10;int c 100;int* p &a;p &b;p &c;如果不加volatile修饰 p , 编译…

团队编程:提升代码质量与知识共享的利器

目录 前言1. 什么是团队编程?1.1 团队编程的起源1.2 团队编程的工作流程 2. 团队编程的优势2.1 提高代码质量2.2 促进知识共享2.3 增强团队协作2.4 提高开发效率 3. 团队编程的挑战3.1 开发成本较高3.2 需要良好的团队协作3.3 个人风格和习惯的差异3.4 长时间的集中…

AI时代算法面试:揭秘高频算法问题与解答策略

三种决策树算法的特点和区别 ID3算法:基本的决策树算法,适用于简单的分类问题C4.5算法:改进了ID3算法,适用于更复杂的分类问题,可以处理连续型数据和缺失值CART算法:更加通用的决策树算法,适用于…

【机器学习】机器学习与自然语言处理的融合应用与性能优化新探索

引言 自然语言处理(NLP)是计算机科学中的一个重要领域,旨在通过计算机对人类语言进行理解、生成和分析。随着深度学习和大数据技术的发展,机器学习在自然语言处理中的应用越来越广泛,从文本分类、情感分析到机器翻译和…

VBA常用的字符串内置函数

前言 在VBA程序中,常用的内置函数可以按照功能分为字符串函数、数字函数、转换函数等等,本节主要会介绍常用的字符串的内置函数,包括Len()、Left()、Mid()、Right()、Split()、String()、StrConV()等。 本节的练习数据表以下表为例&#xff…