ark1974
ark1974

Reputation: 655

Can a non-copyable member be used as alternative to make an object non-copyable?

A class with non-copyable member is said to be also non-copyable. From SO, to make a class non-copyable these are the options:

  1. Use boost::noncopyable
  2. Declare constructor and assignment operator as private.
  3. Delete copy constructor.

    class foo 
    {
        private:
          std::mutex _dummy;
    };
    

Question: Will inclusion of a dummy non-copyable member be used for similar purpose and for simplicity? What are the down-sides?

Upvotes: 0

Views: 457

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473272

Since C++11, the proper idiom for making a class non-copyable is to = delete the copy constructor/assignment operator. That's what C++ programmers are told to do, and that's what other C++ programmers will expect to see when looking for that behavior in your class..

It's fine to have a subobject (member or base class) that is non-copyable, and thus your default copy constructor/assignment operator will be implicitly deleted. But you should only do this for a subobject that happens to be non-copyable. That is, you have a unique_ptr<T> or mutex or whatever as a member because you need a unique_ptr<T> or a mutex as class instance data. Not because you're using it as a hack to make the type non-copyable.

The downsides of using a member subobject for this purpose are:

  1. It muddles the meaning of your code. Your mutex _dummy; example tells me that your type has a mutex in it. If nothing ever uses that variable, then that tells me that your code is rather incoherent; if you don't need a subobject, you don't declare one. = delete is the proper idiom, so it is what you should use.

  2. boost::noncopyable was the C++98/03 idiom because it was an empty class. And thus, common empty base optimization would ensure that it wouldn't take up any space in the derived class. Empty members get no such optimization, so a member boost::noncopyable will always make your class bigger, to no advantage. And while you could point to the upcoming C++20 [[no_unique_address]] attribute, see reason #1.

Upvotes: 3

Related Questions