C++11 =default,=delete

这篇具有很好参考价值的文章主要介绍了C++11 =default,=delete。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++11 =default,=delete

1. 简介

=default 和 =delete 大部分情况下是用在构造函数(ctor)、析构函数、拷贝构造和拷贝赋值函数(这四种函数被称为 Big-Three)中。

如果自己已经有定义了一个 ctor ,那么编译器就不会在给你一个 default ctor。如果你强制加上 =default,就可以重新获得并使用 default ctor。default ctor 就是编译器给的默认的构造函数。如果你没有显式写出构造函数,我们常说有默认的构造函数,其实指的就是这一个。

单纯的 default ctor 没什么用,只是一个空函数,因为编译器不知道你要做什么。但如果有继承关系的话,这个 default ctor 就很有用。因为如果这个类是有继承其他父类的话,且 ctor 是 default ctor 的话,当调用到该类时,如果使用的是 default ctor ,这个 default ctor 里面会帮你调用父类的 ctor。也就是编译器背后会给你加上代码。

·· C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

Big-Three 加上右值引用的构造函数和它的拷贝赋值就是 Big-Five。

2. 示例

如果有一个类 Foo,类中有一个成员变量 _i。

Foo(int i):_i(i){}
Foo() = default;

上面这样写是可以编译通过的,因为构造函数是可以多个的,也就是可以重载,所以上面两个可以并存。

Foo(const Foo& x):_i(x._i){}
//有了上面的,则下面这两个都会报错
Foo(const Foo&) = default;   //报错
Foo(const Foo&) = delete;    //报错

拷贝构造函数只能有一个,不能多个。否则会报如下的错误:
C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

拷贝赋值函数元素同理的。
C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

析构函数也是同理,只能有一个析构函数。
C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

你会想普通函数可以吗?例如下面这样子
C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言
当你在类中定义如上两个成员函数时,使用 =default 会报错,因为编译器不知道你默认是要干嘛的,而且这样写没有意义。而使用 =delete 是可以的,但是就是有点奇怪,因为你如果不要这个函数,就干脆不写出来就可以了。

看到这里,可以总结出:delete 可以用在任意函数上

而这里需要注意的是,=0 只能用在虚函数(virtual)身上。如果你写 void func2() = 0; 就会报错。

3. 当我们写一个空的类,里面就真的是空的吗

C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

当我们写了一个这样的类 class Empty{}; 编译器会默认给我们一个 Big-Three 的类。也就是这个类里面会有默认的构造函数、拷贝构造函数、析构函数和拷贝赋值函数。C++11之后,就是 Big-Five,会多一个移动构造函数(也就是参数是右值引用的)。你可以注意到,这个类默认给的这些函数都是 public 且是 inline。

而你会问编译器这样有什么用?它跟上面讲过的同理,就是为了有继承关系的时候,编译器可以在这些函数中藏一些“幕后操作”的代码,例如一个类B 继承了类 A,B只是如上面一样,是一条语句,也就是一个空类,编译器会帮 B 在 B 类中的 Big-Five 函数增加代码,以便 B 可以正确地生成和释放,会帮助 B 调用 A的构造函数和析构函数。

4. 到底什么样的类需要自己定义 Big-Three

一个类中只要带有指针的成员你就需要自己定义类,自己写出 Big-Three,不能使用默认的。如果一个类中没有指针成员就可以断定大概率不用自己写 Big-Three,使用默认的类就好。

带有指针的话,就有深拷贝和浅拷贝;如果只是单纯地把指针,四个字节拷贝过去,也就是两个指针指向同一块内存,这种就叫浅拷贝。深拷贝则是,指针所指向的那一块内存也要拷贝过去。

例如复数的类,就是可以直接使用默认的 Big-Three。
C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言
复数只有实部、虚部,没有指针,所以拷贝构造和拷贝赋值只是将数据忠实地拷贝过去,所以不需要自己去写一套,可以直接用编译器默认给的。

而 string 类,它的内部就有一个指针,指向一块放字符串的内存。所以 string 类是需要有显式的 Big-Three 的。

5. No-Copy

C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

如果不像一个类可以被拷贝,就可以像上面一样。把拷贝构造和拷贝赋值设置为 delete。

6. No-Dtor(没有析构函数)

C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

如果我们不要析构函数的话,要显式地写出来,赋值为 delete。delete 可以运用于任何成员函数,但是用于析构函数上时,后果自负。因为对象总有离开作用域的时候,但是调用不了析构函数会报错,如上图所示。

7. Private-Copy

C++11 =default,=delete,C++侯捷系列,C++,c++,开发语言

把拷贝构造和拷贝复制放到私有里面,就不允许一些普通的对象可以调用,但允许被友元或者成员函数调用。文章来源地址https://www.toymoban.com/news/detail-814028.html

到了这里,关于C++11 =default,=delete的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • iOS开发系列--Swift语言

    Swift是苹果2014年推出的全新的编程语言,它继承了C语言、ObjC的特性,且克服了C语言的兼容性问题。Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其中你可以看到C#、Java、Javascript、Python等多种语言的影子。同时在2015年的WWDC上苹果还宣布

    2024年02月06日
    浏览(58)
  • C++11补充:智能指针如std::unique_ptr如何添加自定义的deleter

    关于智能指针的问题,有时候为了方便,需要在析构时附加一些清理操作,或者,有的指针本身来自C的库文件中,这时候,就非常期望能够使用自定义的deleter, 但是标准C++创建函数如std::make_unique / std::make_shared 等不支持创建带有自定义deleter的智能指针,这时,我们只能使用

    2024年02月07日
    浏览(47)
  • 解决Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlS..(22.11.20)

    解决过程: 在我们没有开启事务的时候,如果使用mybatis,我们会在日志中看到如下的内容:“Closing non transactional SqlSession”,这种情况说明没有开启Spring的事务管理,因此才会关闭一个非事务的SqlSession。 那么如何开启事务管理呢?最简单的方式就是添加下面两条配置: 然后我

    2024年02月12日
    浏览(38)
  • Android 11 第二个开发者预览版发布,目前支持 Pixel 2/3/3a/4 系列刷机

    今天,谷歌发布了Android 11的第二个开发者预览版。和此前发布的第一个预览版相同,该预览版也仅适用于开发人员,需要手动下载,目前支持Pixel 2/3/3a/4系列刷机。 Android 11的第二个开发者预览版并没有引入任何突破性的新功能,很大程度上是首个预览版的维护升级版本。对

    2024年02月22日
    浏览(48)
  • 鸿蒙开发系列教程(七)--ArkTS语言:状态管理

    如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念 状态管理机制:在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化

    2024年01月20日
    浏览(58)
  • C语言 - 删除数组中的指定元素(Delete)

    目录   引言: 题目说明: 举例分析: 初始状态: step 1:  Step 2:  Step 3 :  Step 4 :  将最后一个元素赋值为0  Step 5 :将i下标向前迁移一位(重复判断): 代码实现:  总结:   这是数组中一个比较简单的题目,今天把它单独拎出来的原因就是在我即将要写的数据结构的顺

    2023年04月09日
    浏览(48)
  • ElasticSearch系列 - SpringBoot整合ES:restHighLevelClient.count(countRequest, RequestOptions.DEFAULT)

    restHighLevelClient.count(countRequest, RequestOptions.DEFAULT) 是 Elasticsearch Java High Level REST Client 中用于执行计数请求的方法。 具体来说,它接受两个参数: countRequest:一个 CountRequest 对象,表示计数请求的参数,包括要计数的索引、查询条件等。 RequestOptions.DEFAULT:一个 RequestOptions 对象

    2024年02月08日
    浏览(58)
  • Groovy开发语言系列(第三篇):DSL的强大能力

    欢迎阅读本系列的第三篇文章!在前两篇中,我们已经介绍了Groovy语言的发展历史、特点以及安装和基本语法。今天,我们将聚焦于Groovy的强大能力之一:领域特定语言(Domain-Specific Language,简称DSL)。 让我们先通过一个简单的示例来吸引大家对DSL的兴趣: 这段代码执行后

    2024年02月12日
    浏览(30)
  • 建站系列(五)--- 前端开发语言之HTML、CSS、JavaScript

    建站系列(一)— 网站基本常识 建站系列(二)— 域名、IP地址、URL、端口详解 建站系列(三)— 网络协议 建站系列(四)— Web服务器之Apache、Nginx 建站系列(五)— 前端开发语言之HTML、CSS、JavaScript 建站系列(六)— 后端开发语言 建站系列(七)— 常用前后端框架

    2024年02月09日
    浏览(52)
  • centos7系列:出现ZooKeeper JMX enabled by default这种错误的解决方法

    本文主要介绍出现ZooKeeper JMX enabled by defaultUsing config: /opt/software/zookeeper/bin/…/conf/zoo.cfgError contacting service. It is probably not running.这种问题的解决方法。 在安装zookeeper时,配置好了zookeeper的环境,但是启动zookeeper时出现错误,无法正常启动,出现启动错误的情况,使用jps命令检

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包