求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
要资料
 
追随技术信仰

随时听讲座
每天看新闻
 
 
C++并发编程(中文版)
前言
第1章 你好,C++的并发世界!
1.1 何谓并发
1.2 为什么使用并发?
1.3 C++中的并发和多线程
1.4 开始入门
1.5 本章总结
第2章 线程管理
2.1 线程管理的基础
2.2 向线程函数传递参数
2.3 转移线程所有权
2.4 运行时决定线程数量
2.5 识别线程
2.6 本章总结
第3章 线程间共享数据
3.1 共享数据带来的问题
3.2 使用互斥量保护共享数据
3.3 保护共享数据的替代设施
3.4 本章总结
第4章 同步并发操作
4.1 等待一个事件或其他条件
4.2 使用期望等待一次性事件
4.3 限定等待时间
4.4 使用同步操作简化代码
4.5 本章总结
第5章 C++内存模型和原子类型操作
5.1 内存模型基础
5.2 C++中的原子操作和原子类型
5.3 同步操作和强制排序
5.4 本章总结
第6章 基于锁的并发数据结构设计
6.1 为并发设计的意义何在?
6.2 基于锁的并发数据结构
6.3 基于锁设计更加复杂的数据结构
6.4 本章总结
第7章 无锁并发数据结构设计
7.1 定义和意义
7.2 无锁数据结构的例子
7.3 对于设计无锁数据结构的指导建议
7.4 本章总结
第8章 并发代码设计
8.1 线程间划分工作的技术
8.2 影响并发代码性能的因素
8.3 为多线程性能设计数据结构
8.4 设计并发代码的注意事项
8.5 在实践中设计并发代码
8.6 本章总结
第9章 高级线程管理
9.1 线程池
9.2 中断线程
9.3 本章总结
第10章 多线程程序的测试和调试
10.1 与并发相关的错误类型
10.2 定位并发错误的技术
10.3 本章总结
第11章 C++11语言特性简明参考(部分)
11.1 右值引用
11.2 删除函数
11.3 默认函数
11.4 常量表达式函数
11.5 Lambda函数
11.6 变参模板
11.7 自动推导变量类型
11.8 线程本地变量
 

 
目录
删除函数
作者:Anthony Williams  译者:陈晓伟
36 次浏览
4次  

A.2 删除函数

有时让类去做拷贝是没有意义的。std::mutex就是一个例子——拷贝一个互斥量,意义何在?std::unique_lock<>是另一个例子——一个实例只能拥有一个锁;如果要复制,拷贝的那个实例也能获取相同的锁,这样std::unique_lock<>就没有存在的意义了。实例中转移所有权(A.1.2节)是有意义的,其并不是使用的拷贝。当然其他例子就不一一列举了。

通常为了避免进行拷贝操作,会将拷贝构造函数和拷贝赋值操作符声明为私有成员,并且不进行实现。如果对实例进行拷贝,将会引起编译错误;如果有其他成员函数或友元函数想要拷贝一个实例,那将会引起链接错误(因为缺少实现):

  1. class no_copies
  2. {
  3. public:
  4. no_copies(){}
  5. private:
  6. no_copies(no_copies const&); // 无实现
  7. no_copies& operator=(no_copies const&); // 无实现
  8. };
  9. no_copies a;
  10. no_copies b(a); // 编译错误

 

在C++11中,委员会意识到这种情况,但是没有意识到其会带来攻击性。因此,委员会提供了更多的通用机制:可以通过添加= delete将一个函数声明为删除函数。

no_copise类就可以写为:

  1. class no_copies
  2. {
  3. public:
  4. no_copies(){}
  5. no_copies(no_copies const&) = delete;
  6. no_copies& operator=(no_copies const&) = delete;
  7. };

 

这样的描述要比之前的代码更加清晰。也允许编译器提供更多的错误信息描述,当成员函数想要执行拷贝操作的时候,可将连接错误转移到编译时。

拷贝构造和拷贝赋值操作删除后,需要

式写一个移动构造函数和移动赋值操作符,与std::thread和std::unique_lock<>一样,你的类是只移动的。

下面清单中的例子,就展示了一个只移动的类。

清单A.2 只移动类

  1. class move_only
  2. {
  3. std::unique_ptr<my_class> data;
  4. public:
  5. move_only(const move_only&) = delete;
  6. move_only(move_only&& other):
  7. data(std::move(other.data))
  8. {}
  9. move_only& operator=(const move_only&) = delete;
  10. move_only& operator=(move_only&& other)
  11. {
  12. data=std::move(other.data);
  13. return *this;
  14. }
  15. };
  16. move_only m1;
  17. move_only m2(m1); // 错误,拷贝构造声明为“已删除”
  18. move_only m3(std::move(m1)); // OK,找到移动构造函数

 

只移动对象可以作为函数的参数进行传递,并且从函数中返回,不过当想要移动左值,通常需要

式的使用std::move()或static_cast<T&&>。

可以为任意函数添加= delete说明符,添加后就说明这些函数是不能使用的。当然,还可以用于很多的地方;删除函数可以以正常的方式参与重载解析,并且如果被使用只会引起编译错误。这种方式可以用来删除特定的重载。比如,当函数以short作为参数,为了避免扩展为int类型,可以写出重载函数(以int为参数)的声明,然后添加删除说明符:

  1. void foo(short);
  2. void foo(int) = delete;

现在,任何向foo函数传递int类型参数都会产生一个编译错误,不过调用者可以

式的将其他类型转化为short:

  1. foo(42); // 错误,int重载声明已经删除
  2. foo((short)42); // OK

您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



36 次浏览
4次