【 C++11 】类的新功能
C++类的新功能
- 一、默认成员函数
- 二、类成员变量初始化
- 三、default关键字
- 四、delete关键字
- 六、final关键字
- 七、override关键字
一、默认成员函数
八个默认成员函数
在C++11之前,一个类中有如下六个默认成员函数:
- 构造函数。
- 析构函数。
- 拷贝构造函数。
- 拷贝赋值函数。
- 取地址重载函数。
- const取地址重载函数。
这里“默认”的意思就是你不写编译器会自动生成,在C++11标准中又增加了两个默认成员函数,分别是移动构造函数和移动赋值重载函数
默认移动构造和默认移动赋值的生成条件
C++11中新增的移动构造函数和移动赋值函数的生成条件如下:
- 移动构造函数的生成条件:没有自己实现移动构造函数,并且没有自己实现析构函数、拷贝构造函数和拷贝赋值函数。
- 移动赋值重载函数的生成条件:没有自己实现移动赋值重载函数,并且没有自己实现析构函数、拷贝构造函数和拷贝赋值函数。
注意: 如果我们自己实现了移动构造或者移动赋值,就算没有实现拷贝构造和拷贝赋值,编译器也不会生成默认的拷贝构造和拷贝赋值。
默认生成的移动构造和移动赋值会做什么?
- 默认生成的移动构造函数:对于内置类型的成员会完成值拷贝(浅拷贝),对于自定义类型的成员,如果该成员实现了移动构造就调用它的移动构造,否则就调用它的拷贝构造。
- 默认生成的移动赋值重载函数:对于内置类型的成员会完成值拷贝(浅拷贝),对于自定义类型的成员,如果该成员实现了移动赋值就调用它的移动赋值,否则就调用它的拷贝赋值。
要想验证默认生成的移动构造和移动赋值确实做了上述工作,这里需要模拟实现一个简化版的string类,类当中只编写了几个我们需要用到的成员函数。
代码如下:
namespace lx
{class Person{public:Person(string name, int age):_name(name),_age(age){}Person(const Person& p){_name = p._name;_age = p._age;}Person& operator=(const Person& p){_name = p._name;_age = p._age;}~Person(){ cout << "~person" << endl;}private:string _name;int _age; }
}
虽然Person类当中没有实现移动构造和移动赋值,但拷贝构造、拷贝赋值和析构函数Person类都实现了,因此Person类中不会生成默认的移动构造和移动赋值,可以通过下面的代码来验证:
int main()
{lx::Person s1("张三", 21);lx::Person s2 = std::move(s1); //想要调用Person默认生成的移动构造return 0;
}
上述代码中用一个右值去构造s2对象,但由于Person类没有生成默认的移动构造函数,因此这里会调用Person的拷贝构造函数(因为使用const修饰,拷贝构造既能接收左值也能接收右值),这时在Person的拷贝构造函数中就会调用string的拷贝构造函数对name成员进行深拷贝。
如果要让Person类生成默认的移动构造函数,就必须将Person类中的拷贝构造、拷贝赋值和析构函数全部注释掉,这时用右值去构造s2对象时就会调用Person默认生成的移动构造函数。
- Person默认生成的移动构造,对于内置类型成员age会进行值拷贝,而对于自定义类型成员name,因为我们的string类实现了移动构造函数,因此它会调用string的移动构造函数进行资源的转移。
- 而如果我们将string类当中的移动构造函数注释掉,那么Person默认生成的移动构造函数,就会调用string类中的拷贝构造函数对name成员进行深拷贝。
要验证Person类中默认生成的移动赋值函数可以用下面的代码,验证方式和上面验证移动构造的方式是一样的。
int main()
{lx::Person s1("张三", 21);lx::Person s2;s2 = std::move(s1); //想要调用Person默认生成的移动赋值return 0;
}
说明一下:
- 我们在模拟实现的string类的拷贝构造、拷贝赋值、移动构造和移动赋值函数中都打印了一条提示语句,因此可以通过控制台输出判断是否调用了对应的函数。
- 由于VS2013没有完全支持C++11,因此上述代码无法在VS2013当中验证,需要使用更新一点的编译器进行验证,比如VS2019。
二、类成员变量初始化
默认生成的构造函数,对于自定义类型的成员会调用其构造函数进行初始化,但并不会对内置类型的成员进行处理。于是C++11支持非静态成员变量在声明时进行初始化赋值,默认生成的构造函数会使用这些缺省值对成员进行初始化。比如:
class Person
{
public://...
private://非静态成员变量,可以在成员声明时给缺省值string _name = "张三"; //姓名int _age = 20; //年龄static int _n; //普通静态成员变量不能给缺省值//const static int _n = 10; //使用const修饰的静态成员变量可以给缺省值,但一般不建议
};
注意: 这里不是初始化,而是给声明的成员变量一个缺省值。
三、default关键字
C++11可以让我们更好的控制要使用的默认成员函数,假设在某些情况下我们需要使用某个默认成员函数,但是因为某些原因导致无法生成这个默认成员函数,这时可以使用default关键字强制生成某个默认成员函数。
例如,下面的Person类中实现了拷贝构造函数:
class Person
{
public://拷贝构造函数Person(const Person& p):_name(p._name), _age(p._age){}
private:string _name; int _age;
};
这时如下代码就无法编译成功了,因为Person类中编写了拷贝构造函数,导致无法生成默认的构造函数,因为默认构造函数生成的条件是没有编写任意类型的构造函数,包括拷贝构造函数。
int main()
{lx::Person s; //没有合适的默认构造函数可用return 0;
}
这时我们就可以使用default关键字强制生成默认的构造函数,如下:
class Person
{
public:Person() = default; //强制生成默认构造函数//拷贝构造函数Person(const Person& p):_name(p._name), _age(p._age){}
private:string _name; int _age;
};
说明一下: 默认成员函数都可以用default关键字强制生成,包括移动构造和移动赋值。
四、delete关键字
当我们想要限制某些默认函数生成时,可以通过如下两种方式:
- 在C++98中,可以将该函数设置成私有,并且只用声明不用定义,这样当外部调用该函数时就会报错。
- 在C++11中,可以在该函数声明后面加上=delete,表示
让编译器不生成该函数的默认版本,我们将=delete修饰的函数称为删除函数。
例如,要让一个类不能被拷贝,可以用=delete修饰将该类的拷贝构造和拷贝赋值。
class Person
{
public:Person(){}
private:Person(const Person&) = delete;Person& operator=(const Person&) = delete;
};
说明一下: 被=delete修饰的函数可以设置为公有,也可以设置为私有,效果都一样。
六、final关键字
final修饰类
被final修饰的类叫做最终类,最终类无法被继承。比如:
//被final修饰,该类不能再被继承
class Person final
{...
};
final修饰虚函数
final修饰虚函数,表示该虚函数不能再被重写,如果子类继承后重写了该虚函数则编译报错。比如:
//父类
class Person
{
public:virtual void Print() final //被final修饰,该虚函数不能再被重写{cout << "hello Person" << endl;}
};
//子类
class child : public Person
{
public:virtual void Print() //重写,编译报错{cout << "hello child" << endl;}
};
七、override关键字
override修饰子类的虚函数,检查子类是否重写了父类的某个虚函数,如果没有没有重写则编译报错。比如:
//父类
class Person
{
public:virtual void Print(){cout << "hello Person" << endl;}
};
//子类
class child : public Person
{
public:virtual void Print() override //检查子类是否重写了父类的某个虚函数{cout << "hello child" << endl;}
};
分享就到这了,如有错误还望指出。
相关文章:
【 C++11 】类的新功能
C类的新功能 一、默认成员函数二、类成员变量初始化三、default关键字四、delete关键字六、final关键字七、override关键字 一、默认成员函数 八个默认成员函数 在C11之前,一个类中有如下六个默认成员函数: 构造函数。析构函数。拷贝构造函数。拷贝赋值…...
防止SQL注入:PHP安全最佳实践
防止SQL注入:PHP安全最佳实践 SQL注入是一种常见的网络攻击方式,攻击者通过向应用程序的SQL查询中插入恶意代码,来获取、操控或破坏数据库中的数据。为了保护PHP应用免受SQL注入攻击,开发者需要遵循一系列安全最佳实践。本文将介…...
自动化生产或质量检测准备工作杂记
自动化生产或质量检测一个流程是: 上料位上料: “上料位”指的是物料被放置以供机器或设备处理的位置。“上料”指的是将物料从存储位置移动到加工或检测位置的过程。移动到对位相机位置: “对位相机”是一种高精度相机,用于精确…...
张志辰医生
在医学领域,北京中医药大学东方医院的张志辰副主任医师宛如一颗璀璨的明星。自 2011 年于北京中医药大学获取博士学位后,他便扎根临床一线,以精湛医术和仁心仁术,为众多患者排忧解难 张志辰曾先后前往北京天坛医院、广东中山医院…...
CodeMirror 如何动态更新definemode
CodeMirror 如何动态更新definemode 问题描述:解决方法: 问题描述: 项目中有一部分用到了CodeMirror组件,其高亮显示的内容需要根据最新的json动态的更新,需要使用definemode自定义高亮内容。 想要的效果如下…...
舵机SG90详解
舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。其中,SG90 舵机以其高效、稳定的性能特点,成为了许多工程师和爱好者的首选,无论是航模、云台、机器人、智能…...
程序设计考题汇总(四:SQL练习)
文章目录 查询结果限制返回行数 查询结果限制返回行数 select device_id from user_profile LIMIT 2;...
明达IOT平台助力工业废水运维智能化
背景简介 相较于生活污水,工业废水的处理挑战性更高,原因在于其源于多样化的工业生产流程,成分复杂且多变,可能包含重金属、有毒化学…...
深入理解 Ansible Playbook:组件与实战
目录 1 playbook介绍 2 YAML语言 2.1语法简介 2.2数据类型 3 Playbook核心组件 3.1 hosts组件 3.2 remote_user组件 3.3 task列表和action组件 3.4 handlers 3.5 tags组件 3.6 其他组件说明 1 playbook介绍 playbook 剧本是由一个或多个"play"组成的列表。…...
JavaEE初阶——多线程(线程安全-锁)
复习上节内容(部分-掌握程度不够的) 加锁,解决线程安全问题。 synchronized关键字,对锁对象进行加锁。 锁对象,可以是随便一个Object对象(或者其子类的对象),需要关注的是ÿ…...
Stable Diffusion 提示词语法
1.提示词基础 1.提示词之间用英文逗号,分隔 2.提示词之间是可以换行的 3.权重默认为1,越靠前权重越高 4.数量控制在75个单位以内 2.提示词各种符号的意义 2.1 ()、[]、{}符号 权重值()小括号[]中括号{}大括号默认1111层()1.1[]0.9{}1.052层(()) 1.121.21[[]]0.920.81{{}}1.…...
【功能安全】安全确认
目录 01 功能安全确认介绍 02 安全确认用例 03 安全确认模板 01 功能安全确认介绍 定义: 来源...
在pycharm2024.3.1中配置anaconda3-2024-06环境
version: anaconda3-2024.06-1 pycharm-community-2024.3.1 1、安装anaconda和pycharm 最新版最详细Anaconda新手安装配置环境创建教程_anaconda配置-CSDN博客 【2024最新版】超详细Pycharm安装保姆级教程,Pycharm环境配置和使用指南,看完这一篇就够了…...
linux不同发行版中的主要差异
一、初始化系统 Linux不同发行版中的系统初始化系统(如 System V init、Upstart 或 systemd) System V init: 历史:System V init 是最传统的 Linux 系统初始化系统,起源于 Unix System V 操作系统。运行级别ÿ…...
概率论得学习和整理29: 用EXCEL 描述二项分布
目录 1 关于二项分布的基本内容 2 二项分布的概率 2.1 核心要素 2.2 成功K次的概率,二项分布公式 2.3 期望和方差 2.4 具体试验 2.5 概率质量函数pmf 和cdf 3 二项分布的pmf图的改进 3.1 改进折线图 3.2 如何生成这种竖线图呢 4 不同的二项分布 4.1 p0.…...
C++打造局域网聊天室第九课: 客户端队列及其处理线程
文章目录 前言一、添加客户端队列的参数初始化二、相关函数总结 前言 C打造局域网聊天室第九课: 客户端队列及其处理线程 一、添加客户端队列的参数初始化 在Server.cpp的 ListenThreadFunc()函数内的其他操作处实现客户端队列的添加。 首先进行部分参数的初始化…...
请求go web后端接口 java安卓端播放视频
前端代码 添加gradle依赖 implementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0 添加访问网络权限 <uses-permission android:name"android.permission.INTERNET" />允许http 请求请求 andro…...
XML Schema 复合类型 - 混合内容
XML Schema 复合类型 - 混合内容 XML Schema 是一种用于定义 XML 文档结构和内容的语言。在 XML Schema 中,复合类型是一种包含其他元素和/或属性的复杂类型。混合内容(Mixed Content)是复合类型的一种特殊形式,它允许元素包含其…...
第8章 搬移特性
8.1 搬移函数 模块化是优秀软件设计的核心所在,好的模块化能够让我在修改程序时只需理解程序的一小部分。为了设计出高度模块化的程序,我得保证互相关联的软件要素都能集中到一块,并确保块与块之间的联系易于查找、直观易懂。同时,…...
ARM/Linux嵌入式面经(五九):海尔
1.以后打算在哪里工作 问题回答: 1. 以后打算在哪里工作? 回答这个问题时,我首先会考虑我的个人目标、职业规划以及家庭和生活因素。从职业发展的角度来看,我希望能够在技术氛围浓厚、创新能力强、且能提供良好职业成长机会的地方工作。具体来说,我对以下几个方向特别感…...
AI对话与提示词--AI对话四象限框架:你与AI的四种协作关系
很多人跟AI聊天,只有一个模式:抛问题,等答案。 这就像去餐厅只会点"随便"——你永远吃不到想吃的菜。 真正高效的AI协作,需要先搞清楚一件事:你和AI之间,到底是谁知道什么。 一个框架ÿ…...
别再傻傻分不清了!LDO和DC-DC到底怎么选?从效率、温升到选型实战一次讲透
LDO与DC-DC终极选型指南:从理论到实战的完整决策框架 在硬件设计领域,电源方案的选择往往决定了整个系统的稳定性与能效表现。面对LDO(低压差线性稳压器)和DC-DC(直流-直流转换器)这两大主流方案࿰…...
Python量化交易系统:专业回测与组合优化
先把最重要的前提说清楚:国内禁止未经许可的程序化自动交易,下面只做量化研究、回测、信号分析,不含实盘自动下单这套是专业完整版量化系统,Python 可直接运行,结构完整、可扩展包含你要的所有高级功能:多股…...
如何实现零配置专业级视频播放体验?mpv_PlayKit配置方案深度解析
如何实现零配置专业级视频播放体验?mpv_PlayKit配置方案深度解析 【免费下载链接】mpv_PlayKit 🔄 mpv player 播放器折腾记录 Windows conf | 中文注释配置 汉化文档 快速帮助入门 | mpv-lazy 懒人包 Win11 x64 config | 着色器 shader 滤镜 filter 整合…...
从零开始掌握drawio:免费开源绘图工具的全方位指南
1. 为什么你需要drawio这款绘图神器 第一次接触drawio是在三年前的一个项目会议上,当时团队需要快速绘制一套系统架构图。同事随手打开浏览器输入app.diagrams.net,五分钟内就搭建出了清晰的流程图框架。那一刻我才发现,原来专业绘图可以如此…...
ai赋能开发:在快马平台用自然语言描述,自动生成java swing计算器代码
最近想用Java Swing开发一个图形化计算器,但作为初学者对Swing库不太熟悉。好在发现了InsCode(快马)平台,它内置的AI辅助开发功能帮我轻松解决了这个问题。整个过程就像有个编程助手在实时指导,特别适合我这种想快速实现功能但又不想深陷语法…...
Cockpit CMS终极扩展开发指南:7步创建自定义字段类型与组件
Cockpit CMS终极扩展开发指南:7步创建自定义字段类型与组件 【免费下载链接】cockpit Add content management functionality to any site - plug & play / headless / api-first CMS 项目地址: https://gitcode.com/gh_mirrors/coc/cockpit Cockpit CMS…...
告别云服务器开销:手把手教你用Docker Compose在本地Linux虚拟机部署Dify
告别云服务器开销:手把手教你用Docker Compose在本地Linux虚拟机部署Dify 在云计算成本不断攀升的今天,越来越多的独立开发者和小团队开始寻求更经济高效的解决方案。对于数据敏感型项目或内部测试环境而言,本地化部署不仅能显著降低长期运营…...
5分钟打造现代化Windows提示界面:ModernFlyouts彻底改变你的系统体验
5分钟打造现代化Windows提示界面:ModernFlyouts彻底改变你的系统体验 【免费下载链接】ModernFlyouts A modern Fluent Design replacement for the old Metro themed flyouts present in Windows. 项目地址: https://gitcode.com/gh_mirrors/mo/ModernFlyouts …...
AI辅助开发:用自然语言描述需求,让快马平台自动生成精准的Copaw自动化脚本
AI辅助开发:用自然语言描述需求,让快马平台自动生成精准的Copaw自动化脚本 最近在做一个自动化测试项目,需要大量使用Copaw框架来模拟用户操作。作为一个刚接触Copaw的新手,最头疼的就是要花大量时间研究各种API和页面元素定位方…...
