【C++11】类的新功能

【C++11】类的新功能

文章目录

  • 【C++11】类的新功能
    • 一、移动构造和移动赋值的特点
    • 二、类成员变量初始化
    • 三、强制生成默认函数的关键字default
    • 四、禁止生成默认函数的关键字delete
    • 五、继承和多态中的fifinal与override关键字

一、移动构造和移动赋值的特点

​ 默认成员函数,原来C++类中,有6个默认成员函数:

  1. 构造函数
  2. 析构函数
  3. 拷贝构造函数
  4. 拷贝赋值重载
  5. 取地址重载
  6. const取地址重载

​ 最重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。

​ C++11新增了两个:移动构造函数和移动赋值运算符重载。针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下:

  • 如果你没有自己实现移动构造函数,且没有实现析构函数、拷贝构造、拷贝赋值重载都没有实现。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。
  • 如果你没有自己实现移动赋值重载函数,且没有实现析构函数、拷贝构造、拷贝赋值重载都没有实现,那么编译器会自动生成一个默认移动赋值。默认生成的移动赋值函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面的移动构造完全类似)
  • 如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。
namespace ljh {class string {public://构造函数string(const char* str = "") {_size = strlen(str);_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}//交换void swap(string& s) {::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}//拷贝构造函数string(const string& s):_str(nullptr), _size(0), _capacity(0){cout << "string(const string& s) - -深拷贝" << endl;string tmp(s._str);swap(tmp);}//移动构造string(string&& s):_str(nullptr), _size(0), _capacity(0){cout << "string(string&& s) - -移动构造" << endl;swap(s);}//赋值重载string& operator=(const string& s) {cout << "string& operator=(const string& s) - -深拷贝" << endl;string tmp(s);swap(tmp);return *this;}//移动赋值string& operator=(string&& s) {cout << "string& operator=(string&& s) - -移动赋值" << endl;swap(s);return *this;}//析构函数~string() {//delete[] _str_str = nullptr;_size = 0;_capacity = 0;}private:char* _str;size_t _size;size_t _capacity;};
}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& operator=(const Person& p) {if (this != &p) {_name = p._name;_age = p._age;}return *this;}//析构函数~Person(){}private:ljh::string _name;//姓名int _age;//年龄
};int main() {Person s1("张三", 21);Person s2 = std::move(s1);//想要调用Person默认生成的移动构造return 0;
}

​ 如上面代码所示,如果你的Person类实现了拷贝构造函数、析构函数或者拷贝赋值重载,那么执行main函数时,我们想的是调用ljh::string里的移动构造,但是结果显示如下:

image-20240907143818328

​ 如果你将Person类中实现的拷贝构造函数、析构函数或者拷贝赋值重载全部注释掉,结果显示如下:
image-20240907144239566

​ 两次运行结果不同的原因就在于,移动构造是一个特殊的默认成员函数,s1是一个左值,通过move函数,转变了性质,变成了右值属性,赋值给了Person s2,按照正常的逻辑应该会去调用s2的移动构造,然后去调用s1的移动构造;但是当你在Person类实现了拷贝构造函数、析构函数或者拷贝赋值重载的时候,编译器不会生成默认的移动构造函数,他就会去调用拷贝构造,进而去调用s1的拷贝构造,这时一次深拷贝。

​ 如果你想要验证移动赋值,代码如下:

int main() {Person s1("张三", 21);Person s2;s2 = std::move(s1); //想要调用Person默认生成的移动赋值return 0;
}

​ 最后执行的结果和上面是类似的,通过这样的测试就能明白移动构造和移动赋值相比其他的默认成员函数有什么样的区别。

二、类成员变量初始化

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

class Person {
public:/*****/
private:ljh::string _name = "张三"; //姓名int _age = 20;             //年龄static int _a; //静态成员变量不能给缺省值
};

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

​ C++11可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用default关键字显示指定移动构造生成。

class Person {
public://拷贝构造函数Person(const Person& p) :_name(p._name),_age(p._age){ }
private:ljh::string _name;//姓名int _age;//年龄
};
int main() {Person s;//没有合适的默认构造函数可用return 0;
}

​ 执行上面的代码,编译器会提示Person类没有默认的构造函数,在类和对象章节,我们知道对于构造函数,是这样定义的,我们不写编译器会默认生成一个构造函数,如果写了则不会生成。Person类中的构造函数虽然是拷贝构造,但他也是构造函数,我们实例化出来的s对象,应该去调用它的默认构造函数,但是编译器没有生成,因为你已经有了拷贝构造。出现这样的情况,我们可以自己写,也可以使用default关键字显示指定默认的构造函数生成;

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

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

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

如果要限制某些默认函数的生成:

  • 在C++98中,是将该函数设置成private,并且只用声明不用定义,这样当外部调用该函数时就会报错。这样只要其他人想要调用就会报错。
  • 在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。
class Person {
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}Person(const Person& p) = delete;
private:ljh::string _name;int _age;
};
int main() {Person s1;Person s2 = s1;Person s3 = std::move(s1);return 0;
}

五、继承和多态中的fifinal与override关键字

​ 在之前多态的博客中,C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,因此:C++11提供了override和fifinal两个关键字,可以帮助用户检测是否重写。

fifinal

  • 修饰类的时候,表示该类不能被继承
  • 修饰虚函数的时候,表示该虚函数不能再被重写
class A final { //直接限制不能被继承(也称最终类)
private:A(int a = 0):_a(a){}
protected:int _a;
};
class B :public A //不能被继承
{};
/***************************************/
class c {
public:virtual void f() final //限制它不能被子类中的虚函数重写{cout << "c::f()" << endl;}
};
class d:public c {
public:virtual void f() //不能被重写{cout << "d::f()" << endl;}
};

​ override:检查子类虚函数是否重写了父类某个虚函数,如果没有重写编译报错。

class Car {
public:virtual void Drive() { }
};
class Benz :public Car {
public:virtual void Drive() override //检查是否完成重写{cout << "Benz - 舒适" << endl;}
};

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

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

相关文章

对一个已经运行的LabVIEW VI进行控制

要对一个已经运行的LabVIEW VI进行控制&#xff0c;可以采用多种方法&#xff0c;这取决于你想要控制的内容以及具体的应用场景。以下是几种常见的实现方式&#xff1a; 1. 使用全局变量或功能全局变量&#xff08;FGV&#xff09; 方法: 你可以创建全局变量或功能全局变量&am…

枚举和联合体

1.枚举类型 1枚举类型的声明 枚举顾名思义就是一一列举。 把可能的取值一一列举。 比如我们现实生活中&#xff1a; 一周的星期一到星期日是有限的7天&#xff0c;可以一一列举 性别有&#xff1a;男、女、保密&#xff0c;也可以一一列举 月份有12个月&#xff0c;也可以一一…

浙大数据结构:02-线性结构4 Pop Sequence

这道题我们采用数组来模拟堆栈和队列。 简单说一下大致思路&#xff0c;我们用栈来存1234.....&#xff0c;队列来存输入的一组数据&#xff0c;栈与队列进行匹配&#xff0c;相同就pop 机翻 1、条件准备 stk是栈&#xff0c;que是队列。 tt指向的是栈中下标&#xff0c;fr…

自然语言处理系列六十三》神经网络算法》LSTM长短期记忆神经网络算法

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列六十三神经网络算法》LSTM长短期记忆神经网络算…

fail to install hcmon driver问题解决

对我搜集到的解决办法进行总结: 没有删除“C:\Windows\System32\drivers”&#xff09;下的 hcmon.sys 驱动文件,删除后重启后安装修改了注册表默认下载位置,使用winR输入regedit,将 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion这个路径下的都改为C…

PyTorch 卷积层详解

PyTorch 卷积层详解 卷积层&#xff08;Convolutional Layers&#xff09;是深度学习中用于提取输入数据特征的重要组件&#xff0c;特别适用于处理图像和序列数据。PyTorch 提供了多种卷积层&#xff0c;分别适用于不同维度的数据。本文将详细介绍这些卷积层&#xff0c;特别…

Java项目: 基于SpringBoot+mysql+maven房屋租赁系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven房屋租赁系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

【鸿蒙】HarmonyOS NEXT星河入门到实战3-ArkTS界面起步开发

目录 一、界面开发布局思路 二、组件的属性方法 三、字体颜色 四、文字溢出省略号、行高 五、Image图片组件 六、输入框与按钮 七、综合实战- 华为登录 八、设计资源-svg图标 前言&#xff1a;HarmonyOS NEXTArkTS界面开发起步。开发工具:仍然是 DevEco Studio 学习界面…

【电子通识】洁净度等级划分及等级标准

洁净度常用于评估半导体、生物制药、医疗、实验室及科研院所、新能源等领域的洁净室、无尘室或者无菌室等环境。 一般来说&#xff0c;晶圆光刻、制造、测试等级为100级或1000级的洁净间&#xff0c;百级洁净间要求空气中0.5微米的尘埃粒子数不得超过每立方米3520个&#xff1b…

Mysql 数据库免费使用

目录 前言 详细步骤 总结 前言 由于工作需要现在打算学习WPF开发&#xff0c;因为需要访问mysql数据&#xff0c;但是又不想在自己电脑上安装。于是就上网试着查了下&#xff0c;发现果然有提供免费数据库服务的网站。nice&#xff01;所以就打算写一篇文章详细记录一下&…

计算机电脑共享文件和打印机共享问题:“计算机无法访问!您可能没有权限使用网络资源。请与这台服务器的管理员联系以查明您是否有访问权限。”解决办法

在Win10系统中&#xff0c;我们在访问局域网共享文件或计算机共享打印机的时候会出现“你可能没有权限使用网络资源 ”。请与这台服务器的管理员联系以查明你是的提示&#xff0c;很多用户不知道如何解决&#xff0c;下面就把正确的解决方法分享给大家&#xff0c;你可能没有权…

C++11线程池、多线程编程(附源码)

Test1 示例源码展示&#xff1a; #include<iostream> #include<thread> #include<string> using namespace std;void printHelloWord(string s) {cout << s << endl;//return; } int main() {string s;s "wegfer";thread thread1(p…

getLocation:fail, the permission value is offline verifying

getLocation:fail, the permission value is offline verifying 后端会根据appid和secret生成 签名&#xff0c;前端wx配置时一定用appid来验证签名的正确 本次错误为配置初始化失败&#xff1a;前端与后端的appId不一致&#xff0c;我的失误也

Linux CentOS 7.9 安装mysql8

1、新建mysql文件夹 数据比较大&#xff0c;所以我在服务器另外挂了一个盘装mysql&#xff0c;和默认安装一个道理&#xff0c;换路径即可 cd ../ //创建文件夹 mkdir mysql //进入mysql文件夹 cd mysql 2、下载mysql8.0安装包并解压、重命名 //下载安装包 wget https://dev…

yolov8 pt转onnx

第一步&#xff1a; 安装onnx pip install --upgrade onnx 第二步&#xff1a; 将以下代码创建、拷贝到yolov8根目录下。具体代码test.py&#xff1a; from ultralytics import YOLO # Load a model model YOLO(yolov8n.pt) # load an official model # Export the mode…

【网络安全】Exif 数据储存型XSS

未经许可,不得转载。 文章目录 Exif步骤Exif EXIF(Exchangeable Image File Format)数据是一种存储在图像文件中的元数据格式,常用于数码照片和扫描图像。它包含了与图像相关的各种信息,比如拍摄日期和时间、相机品牌和型号、拍摄时的设置(如曝光时间、光圈、ISO等)、地…

重庆轨道交通文旅综合体项目创意策划方案

1. 项目背景与文旅融合 本项目响应国家文旅融合战略&#xff0c;以轻轨作为重庆城市新名片&#xff0c;推动文化和旅游深度融合&#xff0c;实现“旅游为载体&#xff0c;文化为灵魂”的发展理念。 2. 国家战略与文旅产业机遇 国家政策支持文旅产业发展&#xff0c;将旅游作…

Temu官方宣导务必将所有的点位材料进行检测-RSL资质检测

关于饰品类产品合规问题宣导&#xff1a; 产品法规RSL要求 RSL测试是根据REACH法规及附录17的要求进行测试。REACH法规是欧洲一项重要的法规&#xff0c;其中包含许多对化学物质进行限制的规定和高度关注物质。 为了确保珠宝首饰的安全性&#xff0c;欧盟REACH法规规定&#…

【生物信息学算法】图算法1:概念和算法

文章目录 1. 图的定义、分类、表达方式图的定义图的分类表达方式Python实现 2.相邻节点和度概念定义python实现 3.路径、距离和搜索路径和距离搜索环 4.图论中的欧拉定理 1. 图的定义、分类、表达方式 图的定义 图G可以由两个集合来定义&#xff0c;即G(V,E)。其中&#xff0…

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒…