Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prevent accidental object copying in C++

Tags:

c++

copying

In our company's coding standard, we have been told to "be aware of the ways (accidental) copying can be prevented".

I am not really sure what this means, but assume that they mean we should stop classes from being copied if this is not required.

What I can think of is as follows:

  1. Make the copy constructor of a class private.
  2. Make the assignment operator (operator=) of a class private.
  3. Make the constructor of a class explicit (to stop classes from being created using incorrect variables).
  4. For all classes that carry out memory allocation and where copying is required, make sure that the copy constructor and assignment operator carry out deep copying rather than shallow copying.

Am I on the right track? Is there anything I might have missed out?

like image 408
Andy Avatar asked Aug 27 '09 09:08

Andy


People also ask

What steps can one follow to prevent copying of objects?

There are three ways to prevent such an object copy: keeping the copy constructor and assignment operator private, using a special non-copyable mixin, or deleting those special member functions. A class that represents a wrapper stream of a file should not have its instance copied around.

How do I make my class non copyable?

class NonCopyable { public: NonCopyable (const NonCopyable &) = delete; NonCopyable & operator = (const NonCopyable &) = delete; protected: NonCopyable () = default; ~NonCopyable () = default; /// Protected non-virtual destructor }; class CantCopy : private NonCopyable {};

What happens if you try and make a copy of an object?

In general, when we try to copy one object to another object, both the objects will share the same memory address. Normally, we use assignment operator, = , to copy the reference, not the object except when there is value type field.

How do I turn off move constructor?

To correct this, remove the move constructor completely. In the case of the class, once a copy constructor is present (user defined), the move is implicitly not generated anyway (move constructor and move assignment operator).


2 Answers

Yes, making assignment operator and copy constructor private will prevent you from creating any copy of object using standart methods (but if you really need a copy of an object you can implement, for example, Copy() method, which will perform deep copy).

Take a look on boost::noncopyable.

Update (re to Tal Pressman):

...you should be aware of these things and watch out that you don't accidentally copy objects you're not supposed to.

Well, I presume, that any accidental copy will be performed using either assignment operator or copy constructor. So making them private actually makes sense: if object copying is costly operation, then copying must be explicit: other developer can unintentionally indirectly call copy op and compiler will inform him, that this is forbidden.

like image 171
Ivan Pouzyrevsky Avatar answered Oct 17 '22 19:10

Ivan Pouzyrevsky


If your coding standard states "be aware of the ways (accidental) copying can be prevented", I'm guessing they aren't just talking about preventing copies from within the classes itself, but about the performance implications of unnecessary / accidental copies when using the classes.

One of the main causes of unnecessarily wasted performance in the code of people new to C++ is unnecessary copying, usually through temporaries. Compilers are getting better and better at deciding when temporaries are not necessary (see "Want speed? Pass by Value", thanks to Konrad's comment), but the best thing to do is to learn to be aware of the inner workings of copying and temporaries in C++ (among others). For me, reading Efficient C++ really got me started.

like image 24
Joris Timmermans Avatar answered Oct 17 '22 20:10

Joris Timmermans