【C++】C++11类的新功能

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》

🌝每一个不曾起舞的日子,都是对生命的辜负


目录

前言

默认成员函数

类成员变量初始化

强制生成默认函数的关键字default

禁止生成默认函数的关键字delete

final 和 override 关键字

final

override


前言

在C++11中,类增加了2个新的默认成员函数,没错就是我们上一篇刚刚学习的移动构造与移动赋值,并且新增了一些功能,比如default、delete、final和override等关键字,让我们一起来探讨一下吧!


欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。 

=========================================================================

GITEE相关代码:🌟樊飞 (fanfei_c) - Gitee.com🌟

=========================================================================


默认成员函数

原有的默认成员函数:

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 拷贝赋值重载
  • 取地址重载
  • const取地址重载

需要复习的小伙伴们自取

【C++】类和对象(中)之构造函数与析构函数icon-default.png?t=N7T8http://t.csdnimg.cn/ds8up【C++】类和对象(中)之拷贝构造与运算符、操作符重载icon-default.png?t=N7T8http://t.csdnimg.cn/XWAA5


C++11在原有6个默认成员函数的基础上,新增了2个:『 移动构造函数』和『 移动赋值重载』。


默认移动构造和移动赋值的生成条件

  • 移动构造函数的生成条件:没有自己实现移动构造函数,并且没有自己实现析构函数、拷贝构造函数和拷贝赋值函数。
  • 移动赋值重载函数的生成条件:没有自己实现移动赋值重载函数,并且没有自己实现析构函数、拷贝构造函数和拷贝赋值函数。

思考:为什么这里析构函数、拷贝构造函数和拷贝赋值函数在一起说?

在实际的类中,这些要写就都写, 不会出现只实现其中一个的情况,因为只有涉及到深拷贝的类才需要自己实现这三个默认成员函数,其他值拷贝的类用默认生成的就行了。

也就是说,移动构造和移动赋值的生成条件与之前六个默认成员函数不同,并不是单纯的没有实现移动构造和移动赋值编译器就会默认生成。

注意: 如果我们自己实现了移动构造或者移动赋值,就算没有实现拷贝构造和拷贝赋值,编译器也不会生成默认的拷贝构造和拷贝赋值。

思考:为什么我们实现了移动语义,编译器就不会默认生成拷贝构造和拷贝赋值了?

因为需要实现移动语义的类,往往需要我们自主实现拷贝构造和拷贝赋值,还记得么:深拷贝的类才需要移动构造和移动赋值,所以往往需要实现移动语义的类,都会实现拷贝构造和拷贝赋值的。


类成员变量初始化

默认生成的构造函数,对于自定义类型的成员会调用其构造函数进行初始化,但并不会对内置类型的成员进行处理。于是C++11支持非静态成员变量在声明时进行初始化赋值,默认生成的构造函数会使用这些缺省值对成员进行初始化。比如:

class Person
{
public://...
private://非静态成员变量,可以在成员声明时给缺省值F::string _name = "樊梓慕"; int _age = 20;           static int _n; //静态成员变量不能给缺省值
};

强制生成默认函数的关键字default

C++11可以让我们更好的控制要使用的默认成员函数,假设在某些情况下我们需要使用某个默认成员函数,但是因为某些原因导致无法生成这个默认成员函数,这时可以使用default关键字强制生成某个默认成员函数。

比如:我们提供了拷贝构造函数,就不会生成默认移动构造了,那么我们可以使用default关键字强制生成移动构造。

class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}Person(const Person& p):_name(p._name), _age(p._age){}Person(Person&& p) = default;
private:F::string _name;int _age;
};
int main()
{Person s1;Person s2 = s1;Person s3 = std::move(s1);return 0;
}

又比如,下面的Person类中实现了拷贝构造函数:

class Person
{
public://拷贝构造函数Person(const Person& p):_name(p._name), _age(p._age){}
private:F::string _name; int _age;      
};

这时如下代码就无法编译成功了,因为Person类中编写了拷贝构造函数,导致无法生成默认的构造函数,因为默认构造函数生成的条件是没有构造函数,而拷贝构造函数是一种特殊的构造函数。

int main()
{Person s; //没有合适的默认构造函数可用return 0;
}

这时我们就可以使用default关键字强制生成默认的构造函数,如下:

class Person
{
public:Person() = default; //强制生成默认构造函数//拷贝构造函数Person(const Person& p):_name(p._name), _age(p._age){}
private:F::string _name; int _age;        
};

注意: 默认成员函数都可以用default关键字强制生成,包括移动构造和移动赋值。


禁止生成默认函数的关键字delete

当我们不希望某些默认函数生成时,比如某个类不期望被拷贝怎么办呢?

在C++98中,我们可以私有化拷贝构造的声明,占住拷贝构造的地即可,目的是为了不让编译器默认生成,注意无需实现拷贝构造定义。

在C++11中,我们可以在该函数声明后面加上=delete,表示让编译器不生成该函数的默认版本,我们将=delete修饰的函数称为『 删除函数』。

class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}Person(const Person& p) = delete;
private:bit::string _name;int _age;
};
int main()
{Person s1;Person s2 = s1;Person s3 = std::move(s1);return 0;
}

final 和 override 关键字

final

1.修饰虚函数,表示该虚函数不能再被重写;

class Car
{
public:virtual void Drive() final {}
};
class Benz :public Car
{
public:virtual void Drive() { cout << "Benz-舒适" << endl; } //err
};

2.修饰类,该类不能被继承


override

override的作用是让编译器帮助用户检查子类虚函数是否重写了父类某个虚函数,如果没有重写编译报错,override作用发生在编译时。

class Car {
public:virtual void Drive() {}
};
class Benz :public Car
{
public:virtual void Drive() override { cout << "Benz-舒适" << endl; }
};

 =========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟~ 点赞收藏+关注 ~🌟

=========================================================================

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基于微信小程序高校体育场管理小程序

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

跨域问题解决方案之CORS

跨域问题解决方案之CORS 文章目录 跨域问题解决方案之CORS概述浏览器的同源策略同源的判定规则目的同源策略的限制范围 浏览器的同源策略为什么会引发跨域问题&#xff1f;CORS规则CORS解决方案CORS方案将请求分为两类举例简单请求预检请求总结学以致用 概述 浏览器安全的基石…

esp32控制舵机---待完善

舵机有三个引脚&#xff0c;分别是电源、电源GND和信号线。如下图所示&#xff1a; ESP32-WROOM-32E的引脚的定义如下&#xff1a; 图来自乐鑫官网:ESP32-DevKitC V4 入门指南 - ESP32 - — ESP-IDF 编程指南 v5.2.1 文档 硬件连接图&#xff1a; 待补充

Failed to resolve import “Home/components/HomeNew.vue“. Does the file exist?

错误信息 [plugin:vite:import-analysis] Failed to resolve import "/apis/home.js" from "src/views/Home/components/HomeNew.vue". Does the file exist? 错误原因 路径错误 解决方法

js的 for in 和 for of 的具体使用和区别

在 JavaScript 中&#xff0c;for...in 和 for...of 是用于迭代对象和数组的两种不同的循环结构。 先说结论&#xff1a; 推荐在循环对象属性的时候&#xff0c;使用for...in,在遍历数组的时候的时候使用for...of。 for...in循环出的是key&#xff0c;for...of循环出的是valu…

面试复盘1 - 测试相关(实习)

写在前&#xff1a;hello&#xff0c;大家早中晚上好~这里是西西&#xff0c;最近有在准备测试相关的面试&#xff0c;特此开设了新的篇章&#xff0c;针对于面试中的问题来做一下复盘&#xff0c;会把我自己遇到的问题进行整理&#xff0c;除此之外还会进行对一些常见面试题的…

蓝桥杯算法题:区间移位

题目描述 数轴上有n个闭区间&#xff1a;D1,...,Dn。 其中区间Di用一对整数[ai, bi]来描述&#xff0c;满足ai < bi。 已知这些区间的长度之和至少有10000。 所以&#xff0c;通过适当的移动这些区间&#xff0c;你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 100…

scss常用混入(mixin)、@inclue

mixin和inclue的基本使用 mixin混入可以用于定义重复使用的样式&#xff0c;比如下面CSS代码 .header {display: flex;justify-content: center;align-items: center;width: 500px;height: 100px; }.footer {display: flex;justify-content: center;align-items: center;width…

Linux C++ 017-运算符重载

Linux C 017-运算符重载 本节关键字&#xff1a;Linux、C、运算符重载、匿名函数 相关库函数&#xff1a; 运算符重载的概念 对已有的运算符重新进行定义&#xff0c;赋予其另外一种功能&#xff0c;以适应不同的数据类型* 运算符重载可以发生函数重载 * 对于内置的数据类型…

动态规划详解(Dynamic Programming)

目录 引入什么是动态规划&#xff1f;动态规划的特点解题办法解题套路框架举例说明斐波那契数列题目描述解题思路方式一&#xff1a;暴力求解思考 方式二&#xff1a;带备忘录的递归解法方式三&#xff1a;动态规划 推荐练手题目 引入 动态规划问题&#xff08;Dynamic Progra…

【并发编程系列】使用 CompletableFuture 实现并发任务处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件

Autodesk AutoCAD 2025 (macOS, Windows) - 自动计算机辅助设计软件 AutoCAD 2024 开始原生支持 Apple Silicon&#xff0c;性能提升至 2 倍 请访问原文链接&#xff1a;https://sysin.org/blog/autodesk-autocad/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

Golang | Leetcode Golang题解之第8题字符串转换整数atoi

题目&#xff1a; 题解&#xff1a; func myAtoi(s string) int {abs, sign, i, n : 0, 1, 0, len(s)//丢弃无用的前导空格for i < n && s[i] {i}//标记正负号if i < n {if s[i] - {sign -1i} else if s[i] {sign 1i}}for i < n && s[i] >…

SQL Server 存储过程:BBS论坛(表结构文档下载及30个存储过程)

基于 Asp.Net 和 SQL Server 实现了一个BBS论坛&#xff0c;论坛功能比较强大&#xff0c;论坛大部分业务逻辑基于存储过程实现&#xff0c;记录一下。 BBS论坛存储过程清单 序号存储过程功能说明1sp_bbs_admin_add添加管理员2sp_bbs_admin_del删除系统管理员3sp_bbs_admin_m…

Spark-Scala语言实战(9)

之前的文章中&#xff0c;我们学习了如何在spark中使用RDD方法的flatMap,take,union。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&am…

【ESP32S3 Sense接入语音识别+MiniMax模型+TTS模块语音播报】

【ESP32S3 Sense接入语音识别MiniMax模型TTS模块语音播报】 1. 前言2. 功能模块概述2.1 语音接入2.2 大模型接入2.3 TTS模块接入 3. 先决条件3.1 环境配置3.2 所需零件3.3 硬件连接步骤 4. 核心代码4.1 源码分享4.2 代码解析 5. 上传验证5.1 对话测试5.2 报错 6. 总结 1. 前言 …

C语言杂谈

努力扩大自己&#xff0c;以靠近&#xff0c;以触及自身以外的世界 文章目录 什么是定义&#xff1f;什么是声明&#xff1f;什么是赋值&#xff1f;什么是初始化&#xff1f;什么是生命周期&#xff1f;什么是作用域&#xff1f;全局变量&#xff1f;局部变量&#xff1f;size…

HCIA-RS基础-VLAN路由

目录 VLAN 路由1. 什么是 VLAN 路由2. VLAN 路由的原理及配置3. VLAN 的缺点和 VLAN Trunking4. 单臂路由配置 总结 VLAN 路由 1. 什么是 VLAN 路由 VLAN 路由是指在虚拟局域网&#xff08;VLAN&#xff09;之间进行路由转发的过程。传统的 VLAN 配置只能在同一个 VLAN 内进行…

简单认识 node 包的幽灵依赖

幽灵依赖的概念与成因 在 Node.js 的包管理生态系统中&#xff0c;特别是使用 npm&#xff08;Node Package Manager&#xff09;作为包管理器时&#xff0c;“幽灵依赖”是指那些没有直接在项目的 dependencies 或 devDependencies 中显式声明&#xff0c;但却能够在项目的依…

LCD1602显示屏

LCD1602显示 概述 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 引脚说明 //电源 VSS -- GND VDD -- 5V //对比度 VO -- GND //控制线 RS -- P1.0 RW -- P1.1 E -- P1.4 //背光灯 A -- 5…