boost::noncopyable学习

在学习boost的时候,发现很多类都继承至boost::noncopyable,那么boost::noncopyable这个类是干什么用的呢?原来boost::noncopyable允许程序实现一个禁止复制的类,即不能使用类的复制构造函数和复制赋值操作符。以前在写程序的时候,经常反复实现一个不可复制的类或者单例类,于是经常性的拷贝、粘贴,不时还有一些小错误发生。现在boost::noncopyable能很轻松的帮你解决些问题,开始学习吧~

相信大家在学习或者工作中自己也写过禁止复制的类,其实原理也很简单,下面就简单的介绍下。
在C++中定义定义一个类时,如果不明确的自己定义复制构造函数和复制赋值操作符,编译器会默认自动生成这两个函数。请看如下代码:

  
  
  1. //自定定义
  2. class empty_class
  3. {
  4. };
  5. //编译器自动生成后真实代码(省略了构造函数和析构函数)
  6. class empty_class
  7. {
  8. public:
  9. empty_class (const empty_class&){...} //复制构造函数
  10. empty_class& operator= (const empty_class&){...} //复制赋值操作符
  11. };

一般情况下,编译器这种默认生成的行为是有用的,比如可以自动支持swap()、符合容器的复制语义、可以放入标准容器处理。但是在有些特殊情况下,我们不需要类的复制语义,其实这样的类实现起来也非常简单,只需要将复制构造函数和复制赋值操作符私有化,请看下面的例子:

  
  
  1. class do_not_copy_class
  2. {
  3. private:
  4. //私有化 声明即可 不用实现
  5. empty_class (const empty_class&);
  6. empty_class& operator= (const empty_class&);
  7. };

但是如果程序中有大量这样的类,重写这样的代码会让人失去耐心,而且代码出现次数越多越容易增大手写出错的几率。

实现一个不可复制的类很简单,只需要从boost::noncopyable类继承即可,noncopyable位于名字空间boost,为了使用noncopyable组件,需要包含头文件<boost/noncopyable>或者<boost/utility.hpp>,其中<boost/utility.hpp>中包含数个小工具的实现,具体用法请看下面的程序:

  
  
  1. #include <iostream>
  2. #include <boost/noncopyable.hpp>
  3. //这里使用默认的私有继承是可以的
  4. //当然我也可以显示写出private或者publiic修饰词,但效果相同的
  5. class do_not_copy_class : boost::noncopyable
  6. {
  7. };
  8. int main(int argc, char *argv[])
  9. {
  10. do_not_copy_class test1;
  11. //编译错误 调用复制构造函数
  12. do_not_copy_class test2(test1);
  13. do_not_copy_class test3;
  14. //编译错误 调用复制赋值操作符
  15. test3 = test1;
  16. return 0;
  17. }

boost::noncopyable的实现原理很简单,代码很少,如下:

  
  
  1. class noncopyable
  2. {
  3. protected:
  4. //默认的构造函数和析构函数是保护的
  5. noncopyable() {}
  6. ~noncopyable() {}
  7. private:
  8. //私有化复制构造函数和复制赋值操作符
  9. noncopyable( const noncopyable& );
  10. const noncopyable& operator=( const noncopyable& );
  11. };

从上面的代码中可以看出,当我们自定义类是boost::noncopyable的子类时,可以在子类中调用boost::noncopyable的构造函数和析构函数,从而完成子类的初始化和析构,但是外面的程序不能调用boost::noncopyable的构造函数和析构函数。子类会继承父类boost::noncopyable的复制构造函数和复制赋值操作符并将其私有化,从而禁止用户从外部访问复制构造函数和复制赋值操作符。
如果使用C++11标准中的defalut(告诉编译器产生一个默认的)和delete(告诉编译器不自动产生)关键字,我们可以将boost::noncopyable的实现改为如下更清晰的形式:

  
  
  1. class noncopyable
  2. {
  3. protected:
  4. //默认的构造函数和析构函数是保护的
  5. //使用编译器的自动产生的默认实现
  6. noncopyable() = default;
  7. ~noncopyable() = default;
  8. //使用delete关键字禁止编译器自动产生复制构造函数和复制赋值操作符
  9. noncopyable( const noncopyable& ) = delete;
  10. const noncopyable& operator=( const noncopyable& ) = delete;
  11. };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值