1、 =default 和=delete 概述

任何事物的出现都必然有着其出现的理由,伴随着每一个新的概念产生都会带来一系列的便利和价值。C++在不断的演变与发展,与此同时,伴随着许多新的特性和功能产生。=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

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

/************************************************************************** File Name: Student.cpp* Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年07月17日 星期二 23时08分20秒************************************************************************/#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个参数的构造函数,但是无参的构造函数,没有提供,因此会报错。解决方式是:在该类中显式的提供无参构造函数,如下:

/************************************************************************** File Name: Student.cpp* Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年07月17日 星期二 23时08分20秒************************************************************************/#include<iostream>
using namespace std;
class Student
{public:Student(){}   //显式说明Student的无参构造函数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;return 0;
}

问题:以 Student(){} 这样的方式来声明无参数构造函数,会带来一个问题,就是使得 其不再是 POD 类型,因此可能让编译器失去对这样的数据类型的优化功能。这是我们不希望看到的。因此最后使用 = default来修饰默认构造函数。

/************************************************************************** File Name: Student.cpp* Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年07月17日 星期二 23时08分20秒************************************************************************/#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;
}

is_pod的详细使用见:https://zh.cppreference.com/w/cpp/types/is_pod

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

C++开发中,我们经常需要控制某些函数的生成。在C++11之前,我们经常的普遍做法是将其声明为类的 private 成员函数,这样若在类外这些这些函数的操作时候,编译器便会报错,从而达到效果。如例2:

/************************************************************************** File Name: Student.cpp* Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年07月17日 星期二 23时08分20秒************************************************************************/#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

 * Author:    The answer* Function:  Other        * Mail:      2412799512@qq.com * Created Time: 2018年07月17日 星期二 23时08分20秒************************************************************************/#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;
}

注:若缺省版本被删除了,重载该函数是非法的

C++11 关键字default和delete相关推荐

  1. C++笔记-C++11中default及delete的使用

    今天在研究某开源事例代码时发现有人用default和delete关键字,在此学习了下,写了个小例子. default和delete只能作用于构造函数和析构函数. default关键字写了后会自动生成某 ...

  2. C++11学习 新特性之 “=default” 、“=delete”

    文章目录 1. =default 和=delete 概述 2. 类与默认函数 3. 使用"=delete"来限制函数生成 4. "=default"使用范围 1 ...

  3. 关于new handler与default、delete关键字

    在https://blog.csdn.net/qq_42604176/article/details/111638568的operate_new源代码长啥样中谈到过new handler. 当oper ...

  4. C++新特性探究(三):=default、=delete

    一. =default   C++的类有四类特殊成员函数,它们分别是:默认构造函数.析构函数.拷贝构造函数以及拷贝赋值运算符.   这些类的特殊成员函数负责创建.初始化.销毁.或者拷贝类的对象.    ...

  5. C++ =default 和 = delete 以及 trival 和 nontrival

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vecto ...

  6. C/C++基础进阶篇:C++11 中引入的 delete 描述符使用场景

    C++11 中引入的 delete 描述符主要有如下两个使用场景: 禁止编译器自动生成拷贝 Effective C++中提到 通过"私有化 + 只声明.不定义" 的方法禁止编译器生 ...

  7. Java关键字default

    default常用于接口中,从它的中文意思行来看,大概能猜个差不多,我们本来写Java接口的时候,是不能有方法体的函数,就类似于C++中的虚函数,default关键字在接口中修饰方法时,方法可以有方法 ...

  8. 41.什么是default关键字? default的作用是?

    什么是default关键字? default的作用是? <1>JDK1.8的新特性!!! <2>default关键字可以在接口中使用,用于修饰方法; <3>使用de ...

  9. 第一篇:C++11关键字

    C++11 关键字共73个. 新增关键字: alignas.alignof.char16_t.char32_t.constexpr.decltype. noexcept.nullptr.static_ ...

  10. C++11新标准 default 和 delete的使用

    写这个知识点的初衷也是在面试的时候被问到过的,由于对C++11新标准不是很了解,所以你懂得...,好了不多说了 首先我们要了解一下C++类中的四类特殊成员函数:分别是默认构造函数.析构函数.拷贝构造函 ...

最新文章

  1. C#调用windows api的要点
  2. 10个免费开源的项目管理工具
  3. nodeJS中读写文件方法的区别
  4. 消息确认机制---confirm异步
  5. 学长毕业日记 :本科毕业论文写成博士论文的神操作20170406
  6. win10访问win7的共享文件夹
  7. Python学会了,然后呢?
  8. Sublime package control错误:There are no packages available for installation
  9. 20220129CTF刷题-- WEB方向
  10. C++ 常用算法之遍历
  11. js设置百分比保留两位小数
  12. Python批量提取Excel文件中的图片
  13. PJzhang:经典子域名爆破工具subdomainsbrute
  14. 证券计算机行业研究,20210630-首创证券-计算机行业深度报告:物联网,研究框架.pdf...
  15. linux git编译安装目录,Linux(centos) 环境下如何源码编译安装git
  16. Vue官方文档代码大全
  17. c语言头随机数文件库,C语言随机数使用方法
  18. shuipFCMS二次开发记录一
  19. android 阿拉伯语文字方向,android – 如何将RTL文本(阿拉伯语)绘制到位图并正确排序?...
  20. 阿里云视频点播服务SDK的使用,视频文件上传测试

热门文章

  1. Citrix XenDesktop 4.0 Setup Wizard crash
  2. Ubuntu 16.04中的Dock的应用顺序调整
  3. 全球信息数据量陡增 大数据应用前景广阔
  4. codeforces 742D Arpa's weak amphitheater and Mehrdad's valuable Hoses ——(01背包变形)
  5. php生成静态页的方法
  6. CIO,你想做一辈子“消防员”吗?
  7. 26.Yii2 启动过程
  8. 56.Linux/Unix 系统编程手册(下) -- SOCKET 介绍
  9. linux input设备冲突,linux input设备怎么固定event handler
  10. 《数学之美》—余弦定理和新闻的分类