0

I am reading Effective C++, in Rule 14: Think carefully about copying behavior in resource-managing classes, there is an example:

class Lock {
  public:
    explicit Lock(Mutex* pm) : mutexPtr(pm) {
      lock(mutexPtr);
    }
    ~Lock() {
      unlock(mutexPtr);
    }
  private:
    Mutex *mutexPtr;
};

It points out that if we construct the Lock as above, there will be a problem if we run the code below:

Mutex m;
Lock ml1(&m);
Lock ml2(ml1);

I think it may because the code may runs like below:

// ml1 constructes
lock(m)
// copy ml2, but ml1.mutexPtr and ml2.mutexPtr both point to m
ml2.mutexPtr = ml1.mutexPtr
// ml1 destructs
unlock(m)
// ml2 destructs
unlock(m)

So the m will be unlock for twice. So is it the real reason that cause the problem below? thx!

Caesium
  • 789
  • 3
  • 7
  • 24

1 Answers1

0

Yes, that is why the author is saying to be careful. If you use a recursive_mutex instead of plain mutex you can simply lock in the copy ctor and copy-assign operator, but if it's a non-recursive mutex it would likely be better to make the lock type non-copyable.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23