2

Most noncopyable objects are noncopyable because it's nonsensical or problematic to have more than one (e.g., std::unique_ptr), but moving them is still fine. But what are some examples where there is good reason to make an object neither copyable nor movable?

Brian Bi
  • 111,498
  • 10
  • 176
  • 312

3 Answers3

5

When it implements the singleton pattern. If there's only ever going to be one and only one instance of a class, then there really is no point to moving or copying it.

wheaties
  • 35,646
  • 15
  • 94
  • 131
  • 1
    That said, nothing should implement the singleton 'pattern' in the first place. – Xeo Feb 28 '14 at 19:52
  • @Xeo I would largely agree but there are cases where it does make sense. I can count on one hand the number of times it has made sense in the past 10 years but when it has... – wheaties Feb 28 '14 at 20:01
1

std::condition_variable (see here: condition_variable).

I suspect due to potential data races when trying to move.

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
1

In the code of large software you find a lot of classes that are noncopiable and/or nonmovable but the noncopyiable/nonmovable base classes are often missing. If you have a complex class that references some other objects with owning reference then that object is often handled as noncopiable unless someone provided a copy constructor that performs deep copying (by copying the referenced objects too). This scenario is quite ordinary and these complex object often don't have a user specified copy constructor. Another problem with copy/move constructors is that they are problematic to maintain, its a common source of error that someone adds a new member to a class but forgets to update a copy/move constructor.

However, in almost all cases you can make a class copyiable with some extra effort by providing your own copy constructor unless it contains something in the reference graph that is explicitly marked as noncopiable.

When does it make sense to make something non-copiable? In some cases the noncopiable object encapsulates something that can be used only by one thread or subsystem at a time, for example a file handle or any other kind of handle to system resources. Sometimes it doesn't make sense to have a copy of such a resource but you can still safely move the value of the handle to another place to another object with a move constructor.

When to make something nonmoveable? Here is an example: Let's say you create a Lock object for inter-thread synchronization. On windows you implement this Lock class with Critical Sections and you put a CRITICAL_SECTION to your class by value. The documentation of InitializeCriticalSection (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683472%28v=vs.85%29.aspx) states that:

A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically opaque.

So it is wise to mark your Lock class as noncopiable and nonmovable. You could make your Lock class moveable by having only a reference to an object that contains a CRITICAL_SECTION, this way only the internal object is nonmoveable while your Lock instance is movable. It wouldn't be wise to copy the Lock instances even this way because you wouldn't be able to copy the internal state of the CRITiCAL_SECTION instance so the copy wouldn't be identical to the original in some way.

So summing it up: Sometimes an object can not be made copiable because of circumstances that can not be influenced from your own code (like CRITICAL_SECTION or some static 3rd party libs) but you can always make your class moveable in worst case by putting some of its nonmovable member variables into internal objects that are held by references. In reality a lot of complex objects in a software are left without nonmovable and noncopiable base classes even if their copying/moving would cause bugs/crashes.

pasztorpisti
  • 3,760
  • 1
  • 16
  • 26