【问题标题】:boost::shared_ptr boost::mutex and copy constructorboost::shared_ptr boost::mutex 和复制构造函数
【发布时间】:2012-03-18 00:37:39
【问题描述】:

我需要保护对我班级中的数据结构的访问。由于我不能拥有互斥锁(因为我无法复制它),我正在考虑拥有 shared_ptr 并将互斥锁保留在那里。这是我的想法的示例代码:

class Sample {
    typedef boost::lock_guard<boost::mutex> AcquireLock;
    boost::shared_ptr<boost::mutex> mutt;

public:
    Sample() : mutt(new boost::mutex) {}

    void Method()
    {
        AcquireLock lock(*mutt);

        //do some work here
    }
};

我有以下问题:

  • 以这种方式使用互斥锁(作为类成员,通过 shared_ptr)是一种不好的做法吗?
  • 我是否应该为这个类设置复制构造函数,因为它通过 shared_ptr 在堆上分配了内存?

编辑:也许我需要提供更多细节: 我将只创建一次此对象并将其保存在 std::vector 中。我不需要复制它,如果向量需要复制,我不希望每个副本都有不同的互斥锁。这就是为什么我认为复制构造函数对我有用。

【问题讨论】:

    标签: c++ boost mutex shared-ptr copy-constructor


    【解决方案1】:

    这种方法非常有效且合法,但请注意,随着您的班级发展,您可能希望将相同的技术应用于更多班级成员。这就是为什么我建议你考虑利用 pImpl idiom:

    // in hpp:
    class Sample
    {
      Impl();
    private:
      struct Impl;
      // compiler generated copy-constructor will copy only this shared_ptr
      shared_ptr<void> pImpl_;
    };
    
    // in cpp:
    struct Sample::Impl
    {
      mutex mut_;
      // put here whatever members you need, extend Impl without affecting the Sample interface
    };
    
    Impl::Impl() : pImpl_(new Impl)
    {}
    

    【讨论】:

      【解决方案2】:

      如果您复制 Sample 对象,将调用复制构造函数,该构造函数可以是编译器自动生成的,也可以是您明确编写的。

      允许复制 Sample 对象是否是个好主意取决于您要执行的操作。 如果允许复制没有意义,则使对象不可复制,例如通过为复制构造函数提供一个私有原型。

      如果您确实想要允许副本,那么您需要决定每个副本是否应该有自己的互斥体,并适当地定义副本构造函数。自动生成的拷贝构造函数只会做一个浅拷贝,所以所有拷贝都会共享互斥体。

      【讨论】:

      • 我会有副本,因为我会将对象保存在 std::vector 中并从那里使用它。除此之外,我不会制作任何副本,所以我认为默认的复制构造函数对我有用。我想知道的是浅拷贝是否会弄乱引用计数或类似的东西,这会在未来引起问题。
      • 为什么不将shared_ptr存储到向量中的Sample对象中,这样就不用担心Sample对象被复制了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多