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

news2024/11/17 14:22:38

👀樊梓慕:个人主页

 🎥个人专栏:《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.coloradmin.cn/o/1567846.html

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

相关文章

2024年阿里云服务器购买、续费、升级优惠活动价格表

2024年阿里云服务器租用费用&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核4G服务…

计算机网络——32差错检测和纠正

差错检测和纠正 错误检测 EDC 差错检测和纠错位&#xff08;冗余位&#xff09; D 数据由差错检测保护&#xff0c;可以包含头部字段 错误检测不是100%可靠的 协议会泄露一些错误&#xff0c;但是很少更长的EDC字段可以得到更好的检测和纠正效果 奇偶校验 单bit奇偶校验 …

【办公类-47-01】20240404 Word内部照片批量缩小长宽(课题资料系列)

作品展示 背景需求 最近在做《运用Python优化3-6岁幼儿学习操作材料的实践研究》的课题研究资料&#xff08;上半学期和下半学期&#xff09;。 将CSDN里面相关的研究照片文字贴入Word后&#xff0c;就发现一张图片就占了A4竖版一页&#xff0c;太大了。我想把word里面的所有…

vue2源码解析——vue中如何进行依赖收集、响应式原理

vue每个组件实例vm都有一个渲染watcher。每个响应式对象的属性key都有一个dep对象。所谓的依赖收集&#xff0c;就是让每个属性记住它依赖的watcher。但是属性可能用在多个模板里&#xff0c;所以&#xff0c;一个属性可能对应多个watcher。因此&#xff0c;在vue2中&#xff0…

Qt + VS2017 创建一个简单的图片加载应用程序

简介&#xff1a; 本文介绍了如何使用Qt创建一个简单的图片加载应用程序。该应用程序可以打开图片文件并在界面上显示选定的图片&#xff0c;并保存用户上次选择的图片路径。 1. 创建项目&#xff1a; 首先&#xff0c;在VS中创建一个新的Qt Widgets应用程序项目&#xff0c;并…

Vulnhub:WESTWILD: 1.1

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 dirmap enm4ulinux sumbclient get flag1 ssh登录 提权 横向移动 get root 信息收集 arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 0…

Springboot Thymeleaf 实现数据添加、修改、查询、删除

1、引言 在Spring Boot中使用Thymeleaf模板引擎实现数据的添加、修改、查询和删除功能&#xff0c;通常步骤如下&#xff1a; 在Controller类中&#xff0c;定义处理HTTP请求的方法。创建Thymeleaf模板来处理表单的显示和数据的绑定。 2、用户数据添加 1、 在Controller类中…

2024年福建三支一扶报名指南—照片<100kb

2024年福建三支一扶报名指南—照片<100kb

目标检测——监控下的汽车

一、重要性及意义 首先&#xff0c;车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像&#xff0c;可以自动检测出图像中的车辆&#xff0c;并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外&#xff0c;…

智能小车测速(3.26)

模块介绍&#xff1a; 接线&#xff1a; VCC -- 3.3V 不能接5V&#xff0c;否则遮挡一次会触发3次中断 OUT -- PB14 测速原理&#xff1a; cubeMX设置&#xff1a; PB14设置为gpio中断 打开定时器2&#xff0c;时钟来源设置为内部时钟&#xff0c;设置溢出时间1s&#xff0c…

通义灵码功能上线:编程挑战中Claude3(opus)领先一步

最近好多AI博主都在推荐通义灵码&#xff0c;我就下载下来体验了一下&#xff0c;而且目前通义灵码暂时不收费&#xff0c;而且还有一个推荐奖励的活动&#xff0c;活动内容如下&#xff1a; 邀请好友达到一定人数&#xff0c;有一些奖励。 我目前看到微软的Azure云有个语音转…

LabVIEW电力设备在线监测系统

LabVIEW电力设备在线监测系统 在电力行业中&#xff0c;变电站的稳定运行对于保障电力系统的安全性和可靠性至关重要。开发了一种基于LabVIEW软件开发的变电站电力设备在线监测系统&#xff0c;实时监控变电站内部的电力设备状态&#xff0c;确保电力传输的高效与安全。通过对…

Java—抽象方法与接口

声明&#xff1a;以下内容是根据B站黑马程序员的Java课程&#xff0b;博主自己的理解整理而成&#xff0c;课程很好&#xff0c;适合初学者学习。 关于此类题目&#xff0c;重要的是识别出用什么来实现&#xff0c;到底是接口还是抽象方法&#xff0c;还是共有的属性等等&…

React之Diff 算法

在 React 中&#xff0c;通过 React.createElement 也能生成一个虚拟 DOM 节点&#xff08;ReactElement&#xff09;。在 React15 及以前&#xff0c;采用了递归的方式创建虚拟 DOM&#xff0c;递归过程是不能中断的。如果组件树的层级很深&#xff0c;递归会占用线程很多时间…

达梦配置ODBC连接

达梦配置ODBC连接 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 下载ODBC包 下载网址&#xff1a;https://www.unixodbc.org/ unixODBC-2.3.0.tar.gz2 编译并…

树状数组-数据结构

树状数组 t[x] 节点的父节点为 t[x lowbit(x)] 整棵树的深度为 log2n 1 1 . add(x,k) 给指定的节点x加上k — 动态的维护前缀和 需要从x开始&#xff0c;向上找到所有父节点&#xff0c;值都加上k 2. ask(x) 求取节点x之前的前缀和 求取单点之前的前缀和只需要累加即可 …

redis群集有三种模式

目录 redis群集有三种模式 redis群集有三种模式 分别是主从同步/复制、哨兵模式、Cluster ●主从复制&#xff1a;主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均…

LeetCode | 数组 | 二分查找 | 35.搜索插入位置【C++】

题目链接 题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出…

数据结构——图的应用(最小生成树,最短路径,拓扑排序,关键路径)

目录 1.最小生成树 1.概念回顾——生成树 2.最小生成树概念 2.构造最小生成树 1.MST性质 2.Prim算法 3.Kruskal 算法 4.两种算法比较 3.最短路径 1.两点间最短路径 2.某源点到其它各点最短路径 3.单源最短路径——用Dijkstra算法 4.所有顶点间的最短路径…

Echarts 自适应宽高,或指定宽高进行自适应

文章目录 需求分析 需求 有一个按钮实现对Echarts的指定缩放与拉长&#xff0c;形成自适应效果 拉长后效果图 该块元素缩短后效果图 分析 因为我习惯使用 ref 来获取组件的 DOM 元素&#xff0c;然后进行挂载 <div ref"echartsRef" id"myDiv" :sty…