文章目录

  • 1、 =default 和=delete 概述
  • 2、 类与默认函数
  • 3、 使用“=delete”来限制函数生成
  • 4、 “=default”使用范围

1、 =default 和=delete 概述

  • =default、=delete 是C++11的新特性,分别为:显式缺省(告知编译器生成函数默认的缺省版本)和显式删除(告知编译器不生成函数默认的缺省版本)。C++11中引进这两种新特性的目的是为了增强对“类默认函数的控制”,从而让程序员更加精准地去控制默认版本的函数。 其具体的功能和使用方法下面将一一道来。

2、 类与默认函数

  • 在讲解关键字 default和delete 之前,先对类和类的默认函数作下描述与说明,从而加深对这两个关键字的理解与认知。既要知其然,也要知其所以然。C++中,当设计与编写一个类时,若不显著写明,则类会默认提供如下几个函数:
         (1)构造函数
         (2)析构函数
         (3)拷贝构造函数
         (4)拷贝赋值函数(operator=)
         (5)移动构造函数

         以及全局的默认操作符函数:
         (1)operator,
         (2)operator &
         (3)operator &&
         (4)operator *
         (5)operator->
         (6)operator->*
         (7)operator new
         (8)operator delete

         注:若我们在类中实现了这些版本之后,编译器便不会生成其对应的默认函数版本,这时需要我们显式的写上其对应的默认函数版本。

#include <iostream>
using namespace std;class Student{public:Student(const int a,const int b):m_a(a),m_b(b){}int getA()const {return m_a;}int getB()const {return m_b;}private:int m_a;int m_b;
};int main(int argc,char **argv){Student stu(1,2);cout << stu.getA() << endl;//1cout << stu.getB() << endl;//2Student stu1; //编译失败,no matching function for call to ‘Student::Student()’return 0;
}
  • 编译报错,提示:Student.cpp: In function ‘int main(int, char**)’:Student.cpp:34:13: error: no matching function for call to ‘Student::Student()’ Student stu1;
  • 例1定义了一个对象stu1,该对象将会使用Student类的无参构造函数,而该默认构造函数在Student类中,我们没有显式的说明。因此,c++编译器在我们提供了该函数实现之后是不会生成与之对应的默认函数版本的。在Student中我们重载了带2个参数的构造函数,但是无参的构造函数,没有提供,因此会报错。

解决办法,在该类别中显示的提供五参数的构造函数

#include <iostream>
using namespace std;class Student{public:Student(){} //显示说明Student的无参构造函数Student(const int a,const int b)
//        :m_a(a)
//        ,m_b(b){{{m_a = a;m_b = b;}int getA()const {return m_a;}int getB()const {return m_b;}private:int m_a;int m_b;
};int main(int argc,char **argv){Student stu(1,2);cout << stu.getA() << endl;//1cout << stu.getB() << endl;//2Student stu1; //编译失败,no matching function for call to ‘Student::Student()’return 0;
}

学习心得

  • :m_a(a),m_b(b)是一个赋值的运算
Student(const int a,const int b):m_a(a),m_b(b){{{}

等效于

Student(const int a,const int b){m_a = a;m_b = b;}
  • 问题:以 Student(){} 这样的方式来声明无参数构造函数,会带来一个问题,就是使得 其不再是 POD 类型,因此可能让编译器失去对这样的数据类型的优化功能。这是不希望看到的。因此最好使用 = default来修饰默认构造函数。
#include<iostream>
using namespace std;
class Student
{public:Student() = default;Student(const int a,const int b):m_a(a),m_b(b){}int getA()const{return m_a;}int getB()const{return m_b;}private:int m_a;int m_b;
};int main(int argc,char **argv)
{Student stu(1,2);cout<<stu.getA()<<endl; //1cout<<stu.getB()<<endl; //2Student stu1;//使用is_pod模板类可以查看某类型是否属于POD类型,若为POD类型,则返回1,反之,返回0std::cout<<is_pod<Student>::value<<std::endl;  //1return 0;
}

3、 使用“=delete”来限制函数生成

  • C++开发中,我们经常需要控制某些函数的生成。在C++11之前,经常的普遍做法是将其声明为类的 private 成员函数,这样若在类外这些这些函数的操作时候,编译器便会报错,从而达到效果。如例2:
#include<iostream>
using namespace std;
class Student
{public:Student() = default;Student(const int a,const int b):m_a(a),m_b(b){}int getA()const{return m_a;}int getB()const{return m_b;}private:Student(const Student& );Student& operator =(const Student& );private:int m_a;int m_b;
};int main(int argc,char **argv)
{Student stu(1,2);cout<<stu.getA()<<endl; //1cout<<stu.getB()<<endl; //2//Student stu1(stu);//报错:Student.cpp:26:5: error: ‘Student::Student(const Student&)’ is private//Student stu1(3,4);//stu1 = stu;//报错:Student.cpp:27:14: error: ‘Student& Student::operator=(const Student&)’ is privatestd::cout<<is_pod<Student>::value<<std::endl;  //return 0;
}
  • 例2代码编译报错,因为在类中,我们将Student的拷贝构造函数和拷贝赋值函数都声明为了 private 属性,因此,当在类外使用拷贝构造和拷贝赋值操作值,编译器会报错。虽然能够达到效果,但是不够直观和简洁。对于追求高效以及简洁来说

这样做有2个问题:
     (1)不是最简化;
     (2)对于友元支持不友好

更为简洁直观的方法是使用: =delete

#include<iostream>
using namespace std;
class Student
{public:Student() = default;Student(const int a,const int b):m_a(a),m_b(b){}int getA()const{return m_a;}int getB()const{return m_b;}Student(const Student& ) = delete;Student& operator =(const Student& ) = delete;private:int m_a;int m_b;
};int main(int argc,char **argv)
{Student stu(1,2);cout<<stu.getA()<<endl; //1cout<<stu.getB()<<endl; //2//Student stu1(stu);//报错:Student.cpp:39:21: error: use of deleted function ‘Student::Student(const Student&)’//Student(const Student& );//Student stu1(3,4);//stu1 = stu;//报错:SStudent.cpp:44:10: error: use of deleted function ‘Student& Student::operator=(const Student&)’std::cout<<is_pod<Student>::value<<std::endl;  //return 0;
}

4、 “=default”使用范围

  • "=default"不仅仅局限于类的定义内,也可以用于类的定义外来修饰成员函数,如例3:
#include<iostream>
using namespace std;
class Student
{public:Student() = default;Student(const int a,const int b):m_a(a),m_b(b){}int getA()const{return m_a;}int getB()const{return m_b;}Student(const Student& ) = delete;Student& operator=(const Student& );private:int m_a;int m_b;
};Student& Student::operator =(const Student& ) = delete;int main(int argc,char **argv)
{Student stu(1,2);cout<<stu.getA()<<endl; //1cout<<stu.getB()<<endl; //2Student stu1(3,4);stu1 = stu;//编译报错:Student.cpp:42:10: error: use of deleted function ‘Student& Student::operator=(const Student&)’std::cout<<is_pod<Student>::value<<std::endl;  //return 0;
}
  • Student& Student::operator =(const Student& ) = delete;

参考链接

  • C++11新特性之 “=default” 、“=delete”

C++11学习 新特性之 “=default” 、“=delete”相关推荐

  1. C++11 的新特性

    C++11 的新特性 1 变量和基本类型 1.1 long long 类型 扩展精度浮点数,10位有效数字 1.2 列表初始化 初始化的几种不同形式,其中用花括号来初始化变量称为列表初始化: 比如: ...

  2. atitit.Oracle 9 10 11 12新特性attilax总结

    atitit.Oracle 9  10 11  12新特性 1. ORACLE 11G新特性 1 1.1. oracle11G新特性 1 1.2. 审计 1 1.3. 1.   审计简介 1 1.4. ...

  3. C++11 标准新特性:委派构造函数

    https://www.ibm.com/developerworks/cn/rational/1508_chenjing_c11/index.html 陈 晶 2015 年 8 月 11 日发布 We ...

  4. Jdk8新特性一:jdk8新特性之default关键字、日期类、Base64类、Optional

    Jdk8新特性一:jdk8新特性之default关键字.日期类.Base64类.Optional 文章目录 Jdk8新特性一:jdk8新特性之default关键字.日期类.Base64类.Option ...

  5. 从Folly源码学C++ 11的新特性

    两年前Facebook发布了他们的C++库,命名为Folly,这是一个在Facebook内部广泛和可重复使用的C++库组件大集合. 但很多成熟的C++开源库已经存在了,为什么又引进一个呢?除了这个库的 ...

  6. C++11 标准新特性: 右值引用与转移语义(点评)

    <<C++11 标准新特性: 右值引用与转移语义>> 原文地址如下 http://www.ibm.com/developerworks/cn/aix/library/1307_ ...

  7. Java复习第11天---11.4---Java8新特性---Stream流常用方法3和综合案例

    Java复习第11天---11.4---Java8新特性---Stream流常用方法3和综合案例 目录 文章目录 1.count:计数-终结方法 2.limit:取前几个元素-延迟方法 3.skip: ...

  8. Java复习第11天---11.3---Java8新特性---Stream流特点和常用方法2

    Java复习第11天---11.3---Java8新特性---Stream流特点和常用方法2 目录 文章目录 1.Stream流特点 2.filter:过滤 3.map:映射 ***后记*** : 内 ...

  9. Java复习第11天---11.2---Java8新特性---Stream流获取方式和常用方法1

    Java复习第11天---11.2---Java8新特性---Stream流获取方式和常用方法1 目录 文章目录 1.Stream流的2中获取方式 1.1.集合的stream方法 1.2.Stream ...

最新文章

  1. AI芯片进入新阶段 哪种企业能胜出?
  2. 10、计算机图形学——几何介绍(曲面的分类以及示例)
  3. 【莓闻】2009年黑莓增长显著 智能手机领域第一
  4. 实验四 恶意代码技术
  5. 使用C#开发一个简单的P2P应用
  6. FFmpeg在Intel GPU上的硬件加速与优化
  7. 64位Visual Studio 2022,微软在下一盘大棋!
  8. 并查集——营救(洛谷 P1396)
  9. (62)Verilog HDL模块例化system Verilog模块
  10. Generate a Simulator Build command
  11. 《HTML5 2D游戏编程核心技术》——第3章,第3.8节绘制动画帧
  12. jquery-galleryview-2.0 漂亮多样化的图片特效(多项自定义)
  13. 常用电子元器件检测方法与经验
  14. Jsp 购物车(oracle数据库)之初级版
  15. blastn、blastp、blastx、tblastn和tblastx的区别与用法
  16. 消防报警图形显示装置linux,中级消防设施操作员考点:消防控制室图形显示装置...
  17. laravel seeder 填充数据
  18. 谈谈Linux发行版的入门选择
  19. 电脑进不去游戏显示重新连接服务器,幻塔无法连接服务器怎么办?游戏进不去解决方法...
  20. 阿里最新秋招面经,腾讯/美团/字节1万道Java中高级面试题

热门文章

  1. 【转】1.1【MySQL】基本SQL语句大全
  2. 【必知必会】pro文件及常用配置
  3. 查询sql语句是否使用索引
  4. musictools怎么用不了_夏天少不了一只草编包,怎么搭配才不像“买菜用”?
  5. 【HDU - 5917】Instability(规律,结论,Ramsey定理,知识点,tricks)
  6. 分类问题的模型评估指标总结
  7. c语言蓝牙接收6,终于搞定了通过两路蓝牙接收数据
  8. 实时监控后台数据 vue_实时数据监控,快速掌握B站爆款视频热度走向
  9. 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-(一千零一拾一元整)输出。...
  10. 基础的shell编程问题(一)