C++11 中 final 和 override 从入门到精通
文章目录
- 一、引言
- 二、`final` 关键字
- 2.1 `final` 关键字的基本概念
- 2.2 `final` 关键字的语法
- 2.3 `final` 关键字的使用示例
- 2.3.1 防止类被继承
- 2.3.2 防止虚函数被重写
- 2.4 `final` 关键字的使用场景
- 2.5 `final` 关键字的注意事项
- 三、`override` 关键字
- 3.1 `override` 关键字的基本概念
- 3.2 `override` 关键字的语法
- 3.3 `override` 关键字的使用示例
- 3.4 `override` 关键字的作用
- 3.5 `override` 关键字的使用场景
- 3.6 `override` 关键字的注意事项
- 四、`final` 和 `override` 的组合使用
- 五、总结
一、引言
在 C++ 编程的世界里,继承和多态是面向对象编程的核心特性。通过继承,我们可以创建新的类,复用现有类的代码;通过多态,我们可以以统一的方式处理不同类型的对象。然而,在实际开发中,我们可能会遇到一些问题,比如不小心重写了基类的虚函数,或者希望某个类不能被继承,某个虚函数不能被重写。为了解决这些问题,C++11 引入了两个重要的关键字:final
和 override
。这两个关键字的引入,使得我们在处理类的继承和虚函数的重写时更加灵活和安全。
二、final
关键字
2.1 final
关键字的基本概念
final
关键字用于限制类的继承和虚函数的重写。当 final
用于类时,表示该类不能被继承;当 final
用于虚函数时,表示该虚函数不能在派生类中被重写。
2.2 final
关键字的语法
- 修饰类:
class ClassName final {// 类的成员
};
- 修饰虚函数:
class Base {
public:virtual void func() final;
};
2.3 final
关键字的使用示例
2.3.1 防止类被继承
class Base final {
public:void foo() {std::cout << "Base::foo()" << std::endl;}
};// 下面的代码将无法通过编译,因为 Base 被声明为 final
// class Derived : public Base {
// public:
// void foo() {
// std::cout << "Derived::foo()" << std::endl;
// }
// };
在这个例子中,Base
类被声明为 final
,因此不能被其他类继承。如果尝试继承 Base
类,编译器会报错。
2.3.2 防止虚函数被重写
class Base {
public:virtual void foo() {std::cout << "Base::foo()" << std::endl;}virtual void bar() final {std::cout << "Base::bar()" << std::endl;}
};class Derived : public Base {
public:void foo() override {std::cout << "Derived::foo()" << std::endl;}// 下面的代码将无法通过编译,因为 bar() 在 Base 中被声明为 final// void bar() override {// std::cout << "Derived::bar()" << std::endl;// }
};
在这个例子中,Base
类的 bar()
函数被声明为 final
,因此在 Derived
类中不能重写该函数。如果尝试重写 bar()
函数,编译器会报错。
2.4 final
关键字的使用场景
- 设计意图明确:明确表示类或函数不应被进一步扩展或修改。
- 防止意外重写:避免派生类意外重写基类的重要虚函数。
- 优化机会:编译器可以对标记为
final
的虚函数进行去虚拟化优化。 - 接口控制:在框架或库设计中控制哪些部分可以被用户扩展。
2.5 final
关键字的注意事项
final
不是虚函数声明的一部分,可以放在函数声明的任何位置(在参数列表后或函数体前)。final
只能用于虚函数和类。final
是一个标识符,在 C++11 之前可以用作变量名等,但在 C++11 及以后它有特殊含义。
三、override
关键字
3.1 override
关键字的基本概念
override
关键字用于显式地表明派生类中的成员函数是重写基类中的虚函数。使用 override
关键字可以提高代码的可读性和安全性,帮助开发者避免一些常见的错误。
3.2 override
关键字的语法
class Base {
public:virtual void func();
};class Derived : public Base {
public:void func() override;
};
3.3 override
关键字的使用示例
class Base {
public:virtual void display() const {std::cout << "Base class display" << std::endl;}
};class Derived : public Base {
public:void display() const override {std::cout << "Derived class display" << std::endl;}
};int main() {Base* basePtr = new Derived();basePtr->display(); // 输出: Derived class displaydelete basePtr;return 0;
}
在这个例子中,Derived
类的 display()
函数重写了 Base
类的 display()
函数,并且使用了 override
关键字。这向编译器明确表明,display()
是对基类虚函数的重写。
3.4 override
关键字的作用
- 防止函数签名不匹配:如果函数签名不完全匹配(比如参数类型或个数不同),编译器会发出错误提示。
- 防止函数名拼写错误:如果函数名拼写错误或参数列表有误,编译器也会给出错误提示。
3.5 override
关键字的使用场景
当派生类需要重写基类中的虚函数时,通常会使用 override
关键字。这种用法可以提高代码的可读性和安全性,防止因为函数签名不同而导致的错误。
3.6 override
关键字的注意事项
override
只能用于派生类中重写基类的虚函数。- 如果基类中没有对应的虚函数,或者函数签名不匹配,编译器将报错。
四、final
和 override
的组合使用
final
和 override
可以组合使用,表示一个虚函数在派生类中被重写,并且在该派生类中是最终的,不能被进一步重写。
class Base {
public:virtual void func() {std::cout << "Base::func()" << std::endl;}
};class Derived : public Base {
public:void func() override final {std::cout << "Derived::func()" << std::endl;}
};class MoreDerived : public Derived {
public:// 下面的代码将无法通过编译,因为 func() 在 Derived 中被声明为 final// void func() override {// std::cout << "MoreDerived::func()" << std::endl;// }
};
在这个例子中,Derived
类的 func()
函数重写了 Base
类的 func()
函数,并且使用了 override
关键字。同时,func()
函数被声明为 final
,因此在 MoreDerived
类中不能重写该函数。
五、总结
final
和 override
是 C++11 引入的两个非常有用的关键字,它们为类的继承和多态机制提供了更多的控制权和明确性。final
关键字用于指示一个类或成员函数不能被继承或覆盖,而 override
关键字用于明确指出派生类中的成员函数旨在覆盖基类中的同名虚拟函数。
通过对 final
和 override
关键字的理解和运用,我们可以更加安全、清晰地设计和实现 C++ 程序。在实际开发中,合理地使用这两个关键字可以提高代码的可读性、安全性和可维护性,避免一些潜在的错误。希望本文能帮助你更好地掌握 final
和 override
关键字的使用,让你的 C++ 编程之路更加顺畅。
相关文章:

C++11 中 final 和 override 从入门到精通
文章目录 一、引言二、final 关键字2.1 final 关键字的基本概念2.2 final 关键字的语法2.3 final 关键字的使用示例2.3.1 防止类被继承2.3.2 防止虚函数被重写 2.4 final 关键字的使用场景2.5 final 关键字的注意事项 三、override 关键字3.1 override 关键字的基本概念3.2 ove…...
跨多个微服务使用 Redis 共享数据时,如何管理数据一致性?
在跨多个微服务使用 Redis 共享数据时,管理数据一致性是一个复杂但至关重要的问题。Redis 本身提供的原子操作和一些数据结构可以提供帮助,但大部分一致性保障需要应用层面的设计和策略。 首先要明确一点:在分布式系统中,强一致性…...
Linux网络——socket网络通信udp
文章目录 UDP通信基础UDP的特点 Linux下UDP通信核心步骤创建UDP套接字绑定本地地址(可选)发送数据函数:sendto()函数原型参数详解典型使用示例 接收数据函数:recvfrom()函数原型参数详解返回值典型使用示例 关键设计原因无连接特性…...

大数据-275 Spark MLib - 基础介绍 机器学习算法 集成学习 随机森林 Bagging Boosting
点一下关注吧!!!非常感谢!!持续更新!!! 大模型篇章已经开始! 目前已经更新到了第 22 篇:大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…...
大模型微调技术全景图:从全量更新到参数高效适配
在预训练大语言模型(LLM)展现出惊人能力之后,如何让这些“通才”模型蜕变为特定领域的“专家”?微调(Fine-Tuning)正是解锁这一潜力的核心技术。本文将深入解析主流微调技术,助你找到最适合任务…...
c++ chrono头文件含义
在C中,<chrono> 是一个标准库头文件,用于处理时间相关的操作,包括时间点、时间间隔和时钟。它提供了一套强大的时间处理功能,支持高精度的时间测量、时间间隔的计算以及时间点的表示。 1. <chrono> 的主要功能 <…...

git互联GitHub 使用教程
一、下载git Git 公司 右键 git config --global user.name "name" git config --global user.email "email" ssh-keygen -t rsa -C email :生成的ssh密钥需要到github 网站中保存ssh 二、GitHub新建repository 三、本地git互联GitHub 找…...
Python爬虫与Java爬虫深度对比:从原理到实战案例解析
在当今数据驱动的时代,网络爬虫技术已成为获取和分析网络数据的重要手段。作为两种最流行的爬虫开发语言,Python和Java各有其独特的优势和适用场景。本文将全面对比Python爬虫与Java爬虫的核心差异,并通过实际代码示例展示它们的具体实现方式,帮助开发者根据项目需求做出合…...
汇编语言综合程序设计:子程序、分支与循环深度解析
本文将通过一个完整的控制台计算器案例,深入探讨汇编语言中子程序、分支结构和循环结构的综合应用,展示模块化编程、输入输出处理和算法实现的核心技术。 一、模块化编程架构设计 1. 系统架构规划 Calculator System ├── main.asm (主程序)…...

SpringBoot+Mysql实现的停车场收费小程序系统+文档
💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

面向对象进阶 | 深入探究 Java 静态成员与继承体系
个人主页 文章专栏 文章目录 个人主页文章专栏 一、static(静态)1.static 静态变量代码展示内存图 2.static 静态方法工具类:练习: 3.static注意事项4.重新认识main方法 二、继承1.继承概述2.继承的特点3.子类到底能继承父类中的…...

人脸识别技术成为时代需求,视频智能分析网关视频监控系统中AI算法的应用
一、应用背景:时代需求与技术革新的双重驱动 1)传统安防系统的困境:传统监控系统依赖人工逐帧筛查海量视频,在人流密集场所极易漏检,且缺乏实时锁定和主动预警能力,面对突发安全事件响应迟缓。 2&a…...
青岛国瑞数据采集网关软件平台:工业互联的智能基石——安全、高效、开放,驱动企业数字化转型
一、产品定位:工业数据的智能枢纽 青岛国瑞数据采集网关软件平台,以“连接万物、赋能智能”为核心理念,专为工业场景打造,解决设备互联、数据互通、业务融合的核心痛点。无需深奥技术背景,通过极简配置,…...
Git的由来与应用详解:从Linux内核到现代开发的革命性工具
1. Git的诞生背景与历史 1.1 Linux内核开发的困境 1991年,Linus Torvalds创建了开源的Linux操作系统。随着Linux的不断发展壮大,全球各地的志愿者纷纷参与到Linux内核的开发中。然而,在2002年之前,Linux内核的代码管理却处于一种原始状态——世界各地的开发者通过diff方式…...
@Prometheus 监控-MySQL (Mysqld Exporter)
文章目录 **Prometheus 监控 MySQL ****1. 目标****2. 环境准备****2.1 所需组件****2.2 权限要求** **3. 部署 mysqld_exporter****3.1 下载与安装****3.2 创建配置文件****3.3 创建 Systemd 服务****3.4 验证 Exporter** **4. 配置 Prometheus****4.1 添加 Job 到 prometheus…...

pc端小卡片功能-原生JavaScript金融信息与节日日历
代码如下 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>金融信息与节日日历</title><…...
窗口聚合窗口聚合
taskmanager.memory.managed.fraction 在 Apache Flink 中,配置项 taskmanager.memory.managed.fraction 用于控制任务管理器(TaskManager)所占用的总内存中,分配给管理内存(Managed Memory)的比例。管理内…...
es在Linux安装
如果服务器能访问外网: wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.0.zip不能就手动下载,解压文件到合适目录 unzip elasticsearch-6.4.0.zip -d /opt/ mv /opt/elasticsearch-6.4.0 /opt/elasticsearch创建和日志…...

Go语言学习-->第一个go程序--hello world!
Go语言学习–>第一个go程序–hello world! 1 写代码前的准备 1 创建编写代码的文件夹 2 使用vscode打开3 项目初始化 **go mod init*(初始化一个go mod)Go Module 是 Go 1.11 版本引入的官方依赖管理系统,用于替代传统的 GOPATH…...

高雄市12岁以下身心障碍儿童口腔保健合作院所名单数据集
描述: 关键字:儿童、口腔、保健、院所、名单 字段特征:序号、院所分级、合作医疗院所、市话、地址 语言:繁体 行数/数量:129行,5列 数据量 :7.27KB 格式:CSV、JSON、XML 目录…...
Spring Boot 自动参数校验
在 Spring Boot 中实现参数自动校验主要依靠 Java Bean Validation API(JSR 380)和 Spring 的集成支持。以下是详细实现步骤: 1. 添加依赖 在 pom.xml 中添加验证依赖: <dependency><groupId>org.springframework.b…...

破局新能源消纳难题!安科瑞智慧能源平台助力10KV配电网重构未来
一、政策驱动:新型配电网迎来 “智慧化” 刚需 随着分布式光伏、工商业储能、电动汽车充电桩等新型电力设施大规模并网,传统 10kV 配电网正面临 “高渗透、强波动、多交互” 的运行挑战。2025 年 6 月 1 日正式实施的《配电网通用技术导则》(…...
推荐10个AI视频生成工具网站
以下是10个AI视频生成工具网站推荐: 国内工具 可灵:由快手AI团队研发,支持文生视频、图生视频、首尾帧设置和运镜调整等功能,生成视频画质高,适合短视频创作、AI唱跳、动画短片等。官网:可灵 即梦&#…...

TIA博途中的程序导出为PDF格式的具体方法示例
TIA博途中的程序导出为PDF格式的具体方法示例 如下图所示,选中想要导出为PDF的程序块,右击选择“打印”, 如下图所示,选择“导出为WPS PDF” 或者“Microsoft Print to PDF”, 如下图所示,设置文档布局相关…...

【大模型:知识图谱】--4.neo4j数据库管理(cypher语法1)
使用neo4j的cypher语法对图数据库进行管理;官网地址:Create, start, and stop databases - Operations Manual 目录 1.neo4j--简介 1.1.Neo4j版本的标准数据库 1.2.默认数据库 1.3.每用户主数据库 1.4.system数据库 2.neo4j--数据库管理 2.1.命名…...
Java 实现下拉框树状结构接口的核心思路
目录 核心思路 1. 定义树节点数据结构 : 2. 获取扁平化数据 : 3. 构建树形结构 : 4. 暴露接口 : TreeService.java:树形构建服务 解释 : 总结 下拉框(Dropdown)展示层级结构数…...

数字化时代养老机构运营实训室建设方案:养老机构运营沙盘实训模块设计
在数字化浪潮席卷各行各业的当下,养老机构运营实训室建设方案中的养老机构运营沙盘实训模块设计,已成为培养专业养老运营人才的关键环节,它需紧密贴合时代需求,构建兼具前瞻性与实用性的实训体系。点击获取实训室建设方案 一、养…...

自由开发者计划 004:创建一个苹果手机长截屏小程序
一. 背景 年初,一个漂亮姐姐突然问我,iphone这么多年一直没法长截屏,你们程序员就没个办法把这个硬伤补上吗? 虎躯一震,脑瓜子嗡嗡的,这么多年的iphone资深用户,最初也不是没有想过这个问题&am…...
【Go语言基础】基本语法
文章目录 一、 程序基本结构二. 词法标记(Lexical Tokens)(编译器解析单元)三、 标识符规则(变量命名规则)四、注释与行分隔符五、关键字与预定义标识符六、 代码示例解析 以下是基于文档的Go语言基础语法总…...

工作流引擎-18-开源审批流项目之 plumdo-work 工作流,表单,报表结合的多模块系统
工作流引擎系列 工作流引擎-00-流程引擎概览 工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求 工作流引擎-02-BPM OA ERP 区别和联系 工作流引擎-03-聊一聊流程引擎 工作流引擎-04-流程引擎 activiti 优…...