C++经典面试题目(十一)
1. final和override关键字
在C++中,final 和 override 是两个用于类继承和成员函数重写的关键字,它们主要在面向对象编程的上下文中使用,以增强代码的可读性和安全性。
1. final 关键字
final 关键字主要有两种用法:
- 用于类:如果一个类被声明为
final,那么它不能被继承。这可以防止其他类从该类派生新的类。
class Base final {// ...
};class Derived : public Base { // 错误:Base 是 final,不能被继承// ...
};
- 用于虚函数:如果一个虚函数被声明为
final,那么它在任何派生类中都不能被重写(override)。这确保了该函数的行为在继承链中保持不变。
class Base {
public:virtual void func() final {// ...}
};class Derived : public Base {
public:void func() override { // 错误:func() 在 Base 中是 final,不能被重写// ...}
};
2. override 关键字
override 关键字用于明确表示一个成员函数是重写基类中的虚函数。如果基类中没有相应的虚函数,编译器会报错。这有助于捕获由于拼写错误或签名不匹配而导致的重写错误。
class Base {
public:virtual void func() {// ...}
};class Derived : public Base {
public:void func() override { // 正确:明确地重写 Base 中的 func()// ...}
};
使用 override 关键字的好处是,如果基类中的函数签名发生变化(例如,参数类型或返回类型更改),或者该函数不再是虚函数,编译器会立即报错,从而帮助开发者及时发现和修复问题。
总的来说,final 和 override 关键字增强了C++中面向对象编程的安全性和代码的可读性。它们使得开发者能够更清晰地表达他们的意图,并减少由于继承和多态性而引起的潜在错误。
2. 宏定义和函数有何区别?
在C++中,宏定义和函数都是用于代码复用的重要工具,但它们之间存在一些重要的区别。
-
定义方式:
- 宏定义:使用预处理器指令
#define进行定义。宏定义是在预处理阶段由预处理器处理的,仅仅是文本替换,不占用任何存储空间。 - 函数:使用函数声明和函数定义进行定义。函数定义在编译阶段处理,并在内存中占用存储空间。
- 宏定义:使用预处理器指令
-
执行方式:
- 宏定义:宏在预处理阶段进行简单的文本替换,没有类型检查,也没有计算过程。因此,如果宏定义中存在错误,可能在编译阶段甚至运行时才能发现。
- 函数:函数在调用时执行,有严格的类型检查,且在执行过程中会有计算过程。如果函数中存在错误,通常会在编译阶段发现。
-
性能:
- 宏定义:宏定义通常比函数调用更快,因为它只是简单的文本替换,没有函数调用的开销。然而,如果宏定义中的代码很复杂,可能会导致代码膨胀,从而影响性能。
- 函数:函数调用通常比宏定义慢一些,因为涉及到函数调用和返回的开销。但是,如果函数被频繁调用,编译器可能会进行优化,减少这种开销。
-
调试:
- 宏定义:由于宏只是文本替换,所以调试起来可能比较困难。当宏中的代码出现问题时,错误可能出现在多个地方,使得调试变得复杂。
- 函数:函数有明确的入口和出口,可以更容易地设置断点进行调试。
-
参数处理:
- 宏定义:宏的参数在替换时不会进行类型检查或计算,只是简单地进行文本替换。因此,如果宏的参数使用不当,可能会导致不可预见的结果。
- 函数:函数的参数在调用时进行类型检查和计算,确保参数的有效性。
总的来说,宏定义和函数各有其优点和缺点。在选择使用宏定义还是函数时,需要根据具体的应用场景和需求进行权衡。一般来说,如果代码逻辑复杂或需要类型检查,建议使用函数;如果代码简单且需要高效执行,可以考虑使用宏定义。
3. sizeof 和strlen 的区别
sizeof和strlen在C++中的主要区别体现在以下三个方面:
- 定义与性质:
sizeof是C++中的一个运算符,用于获取特定类型或对象在内存中所占的字节大小。其值在编译时就已经确定,并且与运行时无关。strlen是一个函数,用于计算字符串的长度,即返回字符串中字符的个数,不包括字符串末尾的空字符’\0’。它是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。
- 参数与适用对象:
sizeof的参数非常灵活,可以是数组、指针、类型、对象、函数等。它不仅可以用于基本数据类型,还可以用于结构体、类、联合体等复合数据类型,甚至还可以对表达式求值,编译器会根据表达式的最终结果类型来确定大小。strlen则只能用char*类型的参数,且该字符串必须是以’\0’结尾的。
- 功能:
sizeof的主要功能是获取保证能容纳实现所建立的最大对象的字节大小。strlen的主要功能是返回字符串的长度。
总的来说,sizeof和strlen在C++中有着不同的定义、性质、参数和功能。sizeof主要用于获取内存大小,而strlen则主要用于计算字符串的长度。根据具体的使用场景和需求,开发者可以选择合适的函数或运算符。
4. 简述strcpy、sprintf 与memcpy 的区别
strcpy、sprintf和memcpy这三个函数在C++中都有其特定的用途,它们之间的主要区别体现在以下几个方面:
-
复制的内容与操作对象:
strcpy,即string copy(字符串复制)的缩写,专门用于复制字符串。它的两个操作对象都是字符串,它将含有’\0’结束符的源字符串复制到目标地址空间。sprintf主要用于格式化字符串并输出到字符数组中。其操作源对象可以是多种数据类型,而目的操作对象是字符串。它类似于printf,但打印的目的地是字符串而不是命令行。memcpy则用于复制任意内容,如字符数组、整型、结构体、类等。其两个操作对象是两个任意可操作的内存地址,并不限于何种数据类型。
-
复制的方法与长度控制:
strcpy在复制字符串时不需要指定长度,它会一直复制到遇到源字符串的结束符’\0’为止。因此,如果目标地址空间不足以容纳源字符串,可能会导致缓冲区溢出。sprintf根据格式化字符串和参数列表来生成并复制字符串,其长度由格式化字符串和参数共同决定。memcpy则是根据第三个参数来决定复制的字节数,从而控制复制的长度。它逐个字节地从源地址复制到目标地址,直到达到指定的字节数。
-
用途与返回值:
strcpy主要用于字符串的复制操作,其返回值的类型为char*,指向目标地址空间。sprintf主要用于生成格式化字符串,其返回值是格式化后的字符串长度(不包括末尾的空字符)。如果发生错误,它可能会返回一个负数。memcpy用于内存内容的复制,其返回值为指向目标地址的指针。
综上所述,这三个函数在复制的内容、操作对象、复制方法、长度控制以及用途等方面存在明显的区别。在实际编程中,应根据具体需求选择适当的函数。
5. 结构体可以直接赋值吗
在C++中,结构体(struct)本身并不直接支持整体赋值操作,就像基本数据类型(如int、float等)那样。然而,可以通过一些方法间接地实现结构体的赋值。
1. 逐个成员赋值
你可以通过逐个成员变量进行赋值来实现结构体的复制。例如:
struct Point {int x;int y;
};int main() {Point p1 = {1, 2};Point p2;p2.x = p1.x;p2.y = p1.y;// 现在 p2 是 p1 的一个副本return 0;
}
2. 构造函数赋值
你可以为结构体定义一个构造函数,以便在创建结构体实例时直接初始化其成员。例如:
struct Point {int x;int y;Point(int a, int b) : x(a), y(b) {} // 构造函数
};int main() {Point p1(1, 2);Point p2 = Point(p1.x, p1.y); // 使用构造函数进行赋值// 或者直接使用另一个 Point 对象进行初始化Point p3 = p1; // 这会调用复制构造函数return 0;
}
在上面的例子中,Point 结构体有一个构造函数,它接受两个整数参数并初始化 x 和 y 成员。在 main 函数中,我们使用这个构造函数来创建一个新的 Point 对象 p2,它的值是 p1 的一个副本。
3. 复制构造函数和赋值运算符重载
C++ 允许你重载结构体的复制构造函数和赋值运算符(operator=),以实现自定义的复制和赋值行为。这通常在你需要执行一些额外的操作(如内存管理、深拷贝等)时非常有用。例如:
struct Point {int x;int y;// 复制构造函数Point(const Point& other) : x(other.x), y(other.y) {}// 赋值运算符重载Point& operator=(const Point& other) {if (this != &other) { // 防止自赋值x = other.x;y = other.y;}return *this;}
};int main() {Point p1(1, 2);Point p2 = p1; // 使用复制构造函数Point p3;p3 = p1; // 使用赋值运算符重载return 0;
}
在这个例子中,我们重载了 Point 结构体的复制构造函数和赋值运算符。这样,当我们创建 p2 并赋值为 p1 时,或者将 p1 赋值给 p3 时,就会调用这些自定义的函数。
总结
虽然C++中的结构体本身不支持直接的整体赋值,但你可以通过逐个成员赋值、使用构造函数、复制构造函数或赋值运算符重载等方法来实现结构体的复制和赋值。选择哪种方法取决于你的具体需求和设计考虑。
相关文章:
C++经典面试题目(十一)
1. final和override关键字 在C中,final 和 override 是两个用于类继承和成员函数重写的关键字,它们主要在面向对象编程的上下文中使用,以增强代码的可读性和安全性。 1. final 关键字 final 关键字主要有两种用法: 用于类&…...
设计模式(6):桥接模式
一.桥接模式核心要点 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关系。 \color{red}{处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立…...
Java切面编程
1.切面编程 无需改变原有类的情况下对业务功能实现扩展或增强。 2.目前最流行的AOP框架有两个,分别为Spring AOP 和 AspectJ。 3.Spring AOP使用纯java实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类织入增强的代码。 …...
微服务demo(二)nacos服务注册与集中配置
环境:nacos1.3.0 一、服务注册 1、pom: 移步spring官网https://spring.io,查看集成Nacos所需依赖 找到对应版本点击进入查看集成说明 然后再里面找到集成配置样例,这里只截一张,其他集成内容继续向下找 我的&#x…...
面试题库二
1、简述TCP/IP的三次握手和四次挥手 TCP(Transmission Control Protocol)是一种可靠的、面向连接的传输层协议,用于在网络中传输数据。在建立连接和断开连接时,TCP 使用了三次握手和四次挥手来确保通信的可靠性和正确性。 三次握手…...
HarmonyOS实战开发-如何实现一个简单的电子相册应用开发
介绍 本篇Codelab介绍了如何实现一个简单的电子相册应用的开发,主要功能包括: 实现首页顶部的轮播效果。实现页面跳转时共享元素的转场动画效果。实现通过手势控制图片的放大、缩小、左右滑动查看细节等效果。 相关概念 Swiper:滑块视图容…...
FFmpeg将绿幕视频处理成透明视频播放
怎么在网页端插入透明视频呢,之前在做Web3D项目时,使用threejs可以使绿幕视频透明显示在三维场景中,但是在网页端怎么让绿幕视频透明显示呢? 如图上图,视频背景遮挡住后面网页内容 想要如下图效果 之前有使用过ffmpeg…...
【2024系统架构设计】案例分析- 4 嵌入式
目录 一 基础知识 二 真题 一 基础知识 1 基本概念 ◆系统可靠性是系统在规定的时间内及规定的环境条件下,完成规定功能的能力,也就是系统无故障运行的概率。或者,可靠性是软件系统在应用或系统错误面前,在意外或错误使用的情况下维持软件系统的功能特性的基本能力。...
基于javaweb(springboot+mybatis)生活美食分享平台管理系统设计和实现以及文档报告
基于javaweb(springbootmybatis)生活美食分享平台管理系统设计和实现以及文档报告 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 …...
【MySQL探索之旅】MySQL数据表的增删查改——约束
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…...
【Linux】体验一款开源的Linux服务器运维管理工具
今天为大家介绍一款开源的 Linux 服务器运维管理工具 - 1panel。 一、安装 根据官方那个提供的在线文档,这款工具的安装需要执行在线安装, # Redhat / CentOScurl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start…...
STM32 软件I2C方式读取AS5600磁编码器获取角度例程
STM32 软件I2C方式读取AS5600磁编码器获取角度例程 🔖本例程使用正点原子例程作为工程模板创建。 📘 硬件电路部分 🌿原理图部分: 🌿PCB布线和电路 📙驱动代码部分 int main(void) {u16 i 0;u16 ra…...
[WTL/Win32]_[初级]_[如何设置ListView的列宽不出现水平滚动条]
场景 开发WTL/Win32的程序时,经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度,当用完100%的宽度来平均分配给列宽时,一加载数据多,就会出现垂直滚动条后,水平滚动条也会同时出现的问题。怎么设置才能让水…...
Mac更换JDK版本
1.确保系统中存在多个Java版本。 在Terminal中执行: /usr/libexec/java_home -V 结果: Matching Java Virtual Machines (2): 11.0.1, x86_64: "Java SE 11.0.1" /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home 1.8.0_2…...
Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发
目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…...
root_fs文件系统结构分析和内核加载流程
目录 概述 1 根文件系统下目录介绍 2 文件系统内容分析 2.1 etc/inittab代码分析 2.2 /etc/init.d/rcS 代码分析 2.3 /etc/mdev.conf代码分析 2.3.1 功能概述 2.3.2 /etc/mdev.conf的详细代码 2.4 /etc/init.d/rcS的源代码文件 3 分析内核中加载root_fs的流程 3.1 调…...
macOS系统配置RUST开发环境
打开rust语言官方网,然后点击马上开始: Rust 程序设计语言 配置RUST开发环境: 使用curl下载rust安装脚本: 复制到终端执行: curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 输入: y 选择默认安装,输入: 1...
Android 15全面解读:性能飙升、隐私守护与智能生活新纪元
1. 更强大的性能 Android 15 带来了一系列性能方面的改进,以确保您的设备在运行应用程序时能够更加流畅。通过对系统进行优化,Android 15 在响应速度和性能方面都有了显著的提升。 这些优化包括: 新一代处理器支持: Android 15 …...
Java项目:80 springboot师生健康信息管理系统
作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色:管理员、宿管、学生 管理员管理宿管员,管理学生,修改密码,维护个人信息。 宿管员…...
云服务器配置 docker-spark
云服务器配置 docker-spark 1. 安装2. 启动3. 查看4. 验证5. 其他 1. 安装 我的服务器是腾讯云轻量应用服务器,2 核 2 G,已经内置了 docker, 配置大概如下: ubuntuVM-20-5-ubuntu --------------------- OS: Ubuntu 22.04 LTS x…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
