title: Thread-safe copy constructor/assignment operator
body: <p>Let's say that we want to make class <code>A</code> thread-safe using an <code>std::mutex</code>. I am having my copy constructor and assignment operator similarly to the code below:</p>
  
  <pre><code>#include &lt;mutex&gt;
  
  class A {
  private:
    int i;
    mutable std::mutex mtx;
  
  public:
    A() : i(), mtx() { }
  
    A(const A&amp; other) : i(), mtx()
    {
      std::lock_guard&lt;std::mutex&gt; _lock(other.mtx);
      i = other.i;
    }
  
    A&amp; operator=(const A&amp; other)
    {
      if (this!=&amp;other) {
        std::lock_guard&lt;std::mutex&gt; _mylock(mtx), _otherlock(other.mtx);
        i = other.i;
      }
      return *this;
    }
  
    int get() const
    {
      std::lock_guard&lt;std::mutex&gt; _mylock(mtx);
      return i;
    }
  };
  </code></pre>
  
  <p>I do not think that it has any problems, other than the possibility of <code>other</code> to be destroyed by another thread before being copied, which I can deal with.</p>
  
  <p>My issue is that I haven't seen this pattern anywhere, so I do not know if people just haven't had a need for that or that it is plainly wrong for reasons I currently don't see.</p>
  
  <p>Thanks</p>
  
  <p><strong>NOTES</strong>: </p>
  
  <p>This is just an example. I can have an arbitrary number of member variables of any type, it does not have to be just an <code>int</code>.</p>
  
  <p>After Martin York's comment for possible deadlocking, this is an updated version that uses copy-and-swap (copy elision is also possible, but it wouldn't handle efficiently the self-assignment case). </p>
  
  <p>I also changed int to T, so people cannot assume that it is a POD.</p>
  
  <pre><code>template&lt;typename T&gt;
  class A {
  private:
    T t;
    mutable std::mutex mtx;
  
  public:
    A() : t(), mtx() { }
  
    A(const A&amp; other) : t(), mtx()
    {
      std::lock_guard&lt;std::mutex&gt; _lock(other.mtx);
      t = other.t;
    }
  
    A&amp; operator=(const A&amp; other)
    {
      if (this!=&amp;other) {
        A tmp(other);
        std::lock_guard&lt;std::mutex&gt; _lock(mtx);
        std::swap(t, tmp.t);
      }
      return *this;
    }
  
    T get() const
    {
      std::lock_guard&lt;std::mutex&gt; _lock(mtx);
      return t;
    }
  
  };
  </code></pre>