【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; }
};

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

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

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

🌟~ 点赞收藏+关注 ~🌟

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

shell的编写

文章目录 1.框架2.命令行3.获取用户命令字符串4.命令行字符串分割5.执行命令和内建命令6.完整代码&#xff1a; 1.框架 我们知道shell是一直存在的&#xff0c;所以首先我们第一步就是要搭建一个框架&#xff0c;使其一直存在。 那么也很简单&#xff0c;一个while循环就可以完…

intellij idea 使用git的 cherry pick 摘取其他分支的comment

cherry pick 摘取其他分支的comment 如果想把 feature_v1.0 分支的comment 摘到 feature_v1.0_new 分支上&#xff0c; 先切换到 feature_v1.0_new分支&#xff0c;这一步不能少了。然后点击 下面菜单栏的 git&#xff0c;点击Local Changes旁边的 Log&#xff0c;这时能看到…

(科研实践篇)大模型相关知识

1.embedding 1.介绍&#xff1a; embedding就是用一个低纬的向量表示一个物品。而这个embedding向量的实质就是使距离相似的向量所对应的物品具有相似的含义&#xff08;参考皮尔逊算法和cos余弦式子&#xff1a;计算相似度&#xff09;简单来说&#xff0c;就是用空间去表示…

一个简单好看的html模板

做一个个人博客第一步该怎么做&#xff1f; 好多零基础的同学们不知道怎么迈出第一步。 那么&#xff0c;就找一个现成的模板学一学呗&#xff0c;毕竟我们是高贵的Ctrl c v 工程师。 但是这样也有个问题&#xff0c;那就是&#xff0c;那些模板都&#xff0c;太&#xff01;…

后端SpringBoot+Mybatis 查询订单数据表奇怪报错加一

排错过程&#xff1a; 看报错意思是SQL语句存在错误&#xff0c;然后使用图形化工具运行这个SQL语句 其实这里稍微细心想一下就能发现问题&#xff0c;但是当时没深入想&#xff0c;就觉得order表前加了数据库名字影响不大&#xff0c;所以感觉SQL语句是没问题的&#xff0c;然…

第十二篇【传奇开心果系列】Python自动化办公库技术点案例示例:深度解读Python自动化操作Word

传奇开心果系列博文 系列博文目录Python自动化办公库技术点案例示例系列 博文目录前言一、Python自动化操作Word介绍二、使用python-docx示例代码二、**使用win32com示例代码**三、使用comtypes示例代码四、使用docx-mailmerge示例代码五、基本操作示例代码六、高级操作示例代码…

讲讲你对数据结构-线性表了解多少?

线性表 - 数组和矩阵 当谈到线性表时&#xff0c;数组和矩阵是两种常见的数据结构。 数组&#xff08;Array&#xff09;&#xff1a; 数组是有序的元素集合&#xff0c;可以通过索引来访问和操作其中的元素。它是最简单、最基本的数据结构之一。数组的特点包括&#xff1a; …

不讲概念,讲实操,mysql 分表模糊查询、分页查询 及 merge 表的使用

1.Mysql merge合并表的要求 1.合并的分表必须是 MyISAM 引擎&#xff0c;MyISAN引擎是不支持事务的。2.Merge表只保证合表后数据唯一性&#xff0c;合表前的数据可能会存在重复。3.表的结构必须一致&#xff0c;包括索引、字段类型、引擎和字符集。4.删除 tb_member1 分表正确…

网络爬虫:爬取假数据

网络爬虫&#xff1a;爬取假数据 文章目录 网络爬虫&#xff1a;爬取假数据前言一、项目介绍&#xff1a;二、项目来源&#xff1a;三、架构图&#xff1a;&#xff08;流程图&#xff09;四、使用了什么技术&#xff1a;&#xff08;知识点&#xff09;五、结果示意图&#xf…

DXP学习001-原理图的全局编辑

目录 一&#xff0c;元件标注的全局编辑 1&#xff0c;元件的标注 1&#xff09;order of processing排序执行顺序 2&#xff09;※matching options匹配选项 3&#xff09;annotate schematic注释原理图 ① schematic sheet ②annotate scope 注释范围 ③order顺序…

SpringCloud Hystrix 服务熔断、服务降级防止服务雪崩

文章目录 SpringCloud Hystrix 熔断器、服务降级防止服务雪崩需求背景引入依赖启动类加Hystrix注解接口配置熔断常规配置超时断开错误率熔断请求数熔断限流 可配置项HystrixCommand.Setter参数Command Properties 服务降级 SpringCloud Hystrix 熔断器、服务降级防止服务雪崩 H…

详解设计模式:单例的进化之路

概念 单例模式(Singleton Pattern)是设计模式中一个重要的模式之一&#xff0c;是确保一个类在任何情况下都绝对只有一个实例。单例模式一般会屏蔽构造器&#xff0c;单例对象提供一个全局访问点&#xff0c;属于创建型模式。 根据初始化时间的不同&#xff0c;可以将单例模式…

SpringCloud - 如何本地调试不会注册到线上环境(Nacos)?

问题描述 有时候我们需要本地调试注册到 Nacos 上&#xff0c;但是会影响线上服务的 Feign 请求打到本地导致不通影响了线上业务。 原因分析 一般最传统的解决方案就是修改本地 bootstrap.yml 的 spring.cloud.nacos.discovery.namespace spring:application:name: app-serv…

c语言--枚举类型(声明、使用、优点)

目录 一、枚举类型的声明二、 枚举类型的优点三、 枚举类型的使用 一、枚举类型的声明 枚举顾名思义就是一一列举。 把可能的取值⼀⼀列举。 比如我们现实生活中&#xff1a; ⼀周的星期⼀到星期日是有限的7天&#xff0c;可以⼀⼀列举 性别有&#xff1a;男、女、保密&#x…

WordPress 6.5 “里贾纳”已经发布

WordPress 6.5 “里贾纳”已经发布&#xff0c;其灵感来自著名爵士小提琴家Regina Carter的多才多艺。雷吉娜是一位屡获殊荣的艺术家和著名的爵士乐教育家&#xff0c;以超越流派而闻名&#xff0c;她在古典音乐方面的技术基础和对爵士乐的深刻理解为她赢得了大胆超越小提琴所能…

YUM仓库和编译安装

目录 一.YUM仓库搭建 1.简介&#xff1a; 2.搭建思路&#xff1a; 3.实验&#xff1a;单机yum的创建 二.编译安装 1.简介 2.安装过程 3.实验&#xff1a;编译安装nginx 一.YUM仓库搭建 1.简介&#xff1a; yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红…

STL——vector容器基本使用与常用接口模拟实现

vector的介绍及使用 vector的介绍 vector是表示可变大小数组的序列容器。 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的…

【Apache Doris】周FAQ集锦:第 1 期

【Apache Doris】周FAQ集锦&#xff1a;第 1 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

SD-WAN国际网络专线:高效、合规且可靠的跨境连接解决方案

在数字化时代&#xff0c;企业对跨境网络连接的需求日益增长。SD-WAN技术作为一种新兴的解决方案&#xff0c;正逐渐成为构建跨境网络连接的首选。本文将探讨SD-WAN国际网络专线的发展现状、合规性要求以及选择时需要考虑的关键因素。 SD-WAN技术&#xff1a;跨境网络连接的新…

STM32F407 FSMC并口读取AD7606

先贴一下最终效果图.这个是AD7606并口读取数据一个周期后的数据结果. 原始波形用示波器看是很平滑的. AD7606不知为何就会出现干扰, 我猜测可能是数字信号干扰导致的. 因为干扰的波形很有规律. 这种现象基本上可以排除是程序问题. 应该是干扰或者数字信号干扰,或者是数字和模拟…