• 巧妙包装解决boost::mutex不能复制问题


    在C++中编写一个类,如果我们没明确的创建 拷贝函数和 opertae=的重载,IDE一般会在编译的时候主动添加;

    在Boost库中,对mutex类没有实现其拷贝和operate=函数,查看其mutex.hpp文件可见如下:

     class mutex:

            public ::boost::detail::underlying_mutex
        {
        private:
            mutex(mutex const&);
            mutex& operator=(mutex const&);
        public:
            mutex()
            {
                initialize();
            }
            ~mutex()
            {
                destroy();
            }

            typedef unique_lock<mutex> scoped_lock;
            typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
        }; 


     这样的问题导致我们在使用mutex时只能全局的去定义它,或者使用指针指向一个全局的mutex对象; 

    下面的定义都是错误的:

    struct A{
      boost::mutex m;
    };


    class B{
       public:     boost::mutex m;}

    尤其当我们使用标准容器,如verctor、map 的时候,执行添加或者赋值操作的时候实际都是通过对象的拷贝来完成的,上面的错误写法将直接无法编译!

    由于mutex对象没有拷贝实现,那我们可能会这样去定义它:

    class A{
      public:
         boost::mutex *m;
         A(){
            m=new boost::mutex();
         }
         ~A(){
            delete m;
          }}

    按照上面的写法看似没有什么问题,我们通过简单的包装,在类构造时创建mutex对象并将指向指向它,在析构函数释放。

    但这样实际还是比摆脱不了,A类创建的对象只能作为全局变量来使用命运,

    当其拷贝的时候 拷贝的是内部成员变量m ,拷贝完成原对象释放后,新拷贝出的对象在执行析构函数时就会产生错误,因为m指向的内存已经被释放过了! 

    这种问题其实是我们在C++开发中,如果类中包含指针类型,且对象有可能产生拷贝时需要特别注意的一个问题;

    这个时候我们需要明确的实现类拷贝函数和operate=重载函数,实现方式如下:

    class video_mutex{
    public:
        boost::mutex* value;
        video_mutex(){
            value=new boost::mutex();
        }
        ~video_mutex(){
            delete value;
        }
        video_mutex(video_mutex const& mutex)
        {
            value=new boost::mutex();
        }
        video_mutex& operator=(video_mutex const& mutext){
            return *this;
        }}; 

    当然这种方法所产生的代价就是频繁new出新的mutex对象 并且释放它 ;

    通过上面的实现,我们就可以放心的进行video_mutex的拷贝,将他push到vector中或者赋值给map['key'] 都不会在有任何问题了。 

  • 相关阅读:
    hdu4717 The Moving Points(二分做法)
    C++中用rand()和srand()产生随机数方法介绍
    教你看懂C++类库函数定义之一---HRESULT 宏
    [置顶] IOS培训资料
    调试出不来 断点不起作用 调试技巧 MyEclipse进不了调试
    [置顶] 编程模仿boost::function和boost::bind
    模拟红外协议接收程序
    Java 使用JDBC、DBCP、C3P0访问数据库
    Linux点亮一个灯
    Makefile解析(最简单的LED)
  • 原文地址:https://www.cnblogs.com/cxwx/p/2738934.html
Copyright © 2020-2023  润新知