1 背景问题

对于 C++ 的类,如果程序员没有为其定义特殊成员函数,那么在需要用到某个特殊成员函数的时候,编译器会隐式的自动生成一个默认的特殊成员函数,比如拷贝构造函数,或者拷贝赋值操作符。例如:

  • demo1
class X{
public: X();
}; int main()
{ X x1; X x2 = x1;   // 正确,调用编译器隐式生成的默认拷贝构造函数X x3; x3 = x1;     // 正确,调用编译器隐式生成的默认拷贝赋值操作符
}

在 demo1 中,程序员不需要自己手动编写拷贝构造函数以及拷贝赋值操作符,依靠编译器自动生成的默认拷贝构造函数以及拷贝赋值操作符就可以实现类对象的拷贝和赋值。这在某些情况下是非常方便省事的,但是在某些情况下,假设我们不允许发生类对象之间的拷贝和赋值,可是又无法阻止编译器隐式自动生成默认的拷贝构造函数以及拷贝赋值操作符,那这就成为一个问题了。

2 Deleted 函数的提出

为了能够让程序员显式的禁用某个函数,C++11 标准引入了一个新特性:deleted 函数。程序员只需在函数声明后加上=delete;,就可将该函数禁用。例如,我们可以将类 X 的拷贝构造函数以及拷贝赋值操作符声明为 deleted 函数,就可以禁止类 X 对象之间的拷贝和赋值。

  • demo2
class X {public: X(); X(const X&) = delete;  // 声明拷贝构造函数为 deleted 函数X& operator = (const X &) = delete;  // 声明拷贝赋值操作符为 deleted 函数
}; int main()
{ X x1; X x2 = x1;   // 错误,拷贝构造函数被禁用X x3; x3 = x1;     // 错误,拷贝赋值操作符被禁用
}

在 demo2 中,虽然只显式的禁用了一个拷贝构造函数和一个拷贝赋值操作符,但是由于编译器检测到类 X 存在用户自定义的拷贝构造函数和拷贝赋值操作符的声明,所以不会再隐式的生成其它参数类型的拷贝构造函数或拷贝赋值操作符,也就相当于类 X 没有任何拷贝构造函数和拷贝赋值操作符,所以对象间的拷贝和赋值被完全禁止了。

3 Deleted 函数定义语法

Deleted 函数是 C++11 标准引入的函数定义新语法,deleted 函数定义的语法如图 1 所示:

图 1. Deleted 函数定义语法图

4 Deleted 函数的用法及示例

Deleted 函数特性还可用于禁用类的某些转换构造函数,从而避免不期望的类型转换。在 demo3 中,假设类 X 只支持参数为双精度浮点数 double 类型的转换构造函数,而不支持参数为整数 int 类型的转换构造函数,则可以将参数为 int 类型的转换构造函数声明为 deleted 函数。

  • demo3
class X {public: X(double);X(int) = delete;
}; int main()
{X x1(1.2);X x2(2); // 错误,参数为整数 int 类型的转换构造函数被禁用
}

Deleted 函数特性还可以用来禁用某些用户自定义的类的 new 操作符,从而避免在自由存储区创建类的对象。例如:

  • demo4
#include <cstddef>
using namespace std; class X {
public: void *operator new(size_t) = delete; void *operator new[](size_t) = delete;
}; int main()
{ X *pa = new X;  // 错误,new 操作符被禁用X *pb = new X[10];  // 错误,new[] 操作符被禁用
}

必须在函数第一次声明的时候将其声明为 deleted 函数,否则编译器会报错。即对于类的成员函数而言,deleted 函数必须在类体里(inline)定义,而不能在类体外(out-of-line)定义。例如:

  • demo5
class X {
public:  X(const X&);
}; X::X(const X&) = delete;   // 错误,deleted 函数必须在函数第一次声明处声明

虽然 defaulted 函数特性规定了只有类的特殊成员函数才能被声明为 defaulted 函数,但是 deleted 函数特性并没有此限制。非类的成员函数,即普通函数也可以被声明为 deleted 函数 。例如:

  • demo6
int add (int,int) = delete; int main()
{ int a, b; add(a,b);  // 错误,函数 add(int, int) 被禁用
}

值得一提的是,在 demo6 中,虽然 add(int, int)函数被禁用了,但是禁用的仅是函数的定义,即该函数不能被调用。但是函数标示符 add 仍是有效的,在名字查找和函数重载解析时仍会查找到该函数标示符。如果编译器在解析重载函数时,解析结果为 deleted 函数,则会出现编译错误。例如:

  • demo7
#include <iostream>
using namespace std;int add(int,int) = delete;double add(double a,double b)
{ return a + b;
}int main(){cout << add(1,3) << endl;    // 错误,调用了 deleted 函数 add(int, int) cout << add(1.2,1.3) << endl; return 0;
}

C++11_关键字_Deleted相关推荐

  1. python类方法和实例方法syntax errors_《Fluent Python》CH.11_面向对象_接口:从协议到抽象基类...

    主要内容 首先,本章说明抽象基类的常见用途:实现接口时作为超类使用 说明抽象基类如何检查具体子类是否符合接口定义,以及如何使 用注册机制声明一个类实现了某个接口,而不进行子类化操作 最后, 说明如何让 ...

  2. c语言中external,static关键字用法

    static用法: 在C中,static主要定义全局静态变量.定义局部静态变量.定义静态函数. 1.定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量.全局静态变量有 ...

  3. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  4. volatile关键字之全面深度剖析

    引言 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字 ...

  5. mysql屏蔽关键字实现方法_PHP屏蔽过滤指定关键字的方法

    本文实例讲述了PHP屏蔽过滤指定关键字的方法.分享给大家供大家参考.具体分析如下: 实现思路: 一.把关键字专门写在一个文本文件里,每行一个,数量不限,有多少写多少. 二.PHP读取关键字文本,存入一 ...

  6. Java 静态变量,静态方法,静态常量(java static 关键字)

    Java 静态变量,静态方法,静态常量  就是变量 ,方法,常量前面添加了static 关键字 为什么要使用静态的呢 有时候在处理问题时会需要两个类在同一个内存区域共享一个数据, 不如现在 Main ...

  7. Java this 关键字使用

    this 引用就是本类的一个对象 理解这句话看下面一段代码 package me; public class Me {String name; //成员变量int age;public Me(Stri ...

  8. java 关键字(面试题)

    学而时习之,温故而知新. 今天群里有人问java中true ,false 是关键字吗, 这里记录下,不是关键字,我还特意翻看之前的书看看 下面是 Java 语言保留使用的 50 个关键字: 关键字 g ...

  9. java中标识符,关键字,数据类型

    什么是标识符? 在java语言中用来给一个类,变量或方法命名的符号 标识符的命名规则 标识符可以由字母.数字.下划线(_).美元符($)组成,但不能包含 @.%.空格等其它特殊字符,不能以数字开头. ...

最新文章

  1. java泛型中?和T有什么区别?
  2. 使用职责链模式来重构你的代码
  3. 《Ext JS 高级程序设计》的目录与样张
  4. 单页面应用SPA的优缺点
  5. C语言调用python代码
  6. 将JINQ与JPA和H2一起使用
  7. LeetCode算法入门- Remove Duplicates from Sorted Array -day21
  8. 【转】[原创]LoadRunner如何监控Linux系统资源
  9. php 去除单引号,php如何去除双引号
  10. 淘宝商品评论获取评论
  11. 手机显示主服务器连接异常怎么办,手机主服务器连接配置异常
  12. 随机游走模型 matlab,随机游走的matlab实现
  13. 远程粒子计数器助力药企环境监测 为洁净卫生护航
  14. 透明导航 html,导航栏(Nav) 全透明效果的一种另类实现
  15. Linux修改默认登录端口22
  16. 因为你是我的英雄音译_我可以成为你的英雄宝贝
  17. 【Linux】定时任务 | crontab定时任务
  18. J0ker的CISSP之路:复习-安全架构和设计1
  19. 凡人修仙传之百炼冥门java_修仙缘:细说我与《凡人修仙传》的过往
  20. TCP协议和UDP协议的区别及其应用

热门文章

  1. 什么是 DNS DKIM 记录?
  2. 除了巴菲特,你应该知道投资大师之————巴尔·罗森伯格
  3. 【BZOJ4184】shallot(线段树分治,线性基)
  4. Alpha多样性 Beta多样性
  5. 编译原理实验一PL/0词法分析器c++
  6. .git/hooks/pre-commit: line 6: mvn: command not found
  7. 【2012Esri中国用户大会讲座】ArcGIS 10.1 for Server 安全机制(2)使用Token
  8. 曼彻斯特编码 差分曼彻斯特编码 计算机网络
  9. Sublime Text高效编辑verilog (自动补全)
  10. sa6125平台 机器异常后进入recovery