4

Let's say I have a simple c++ component called Component like this :

class Component {
 public:
  explicit Component(int i)
  : _integer(i) {
  }

  ~Component() {
  }

  private:
   int _integer;

  Component(const Component&);
  Component& operator=(const Component&);
};

I usually found in the code I read the two last instructions but I do not really understand it. Is it mandatory for the correct use of the component ?

klaus
  • 754
  • 8
  • 28
  • 3
    usually it is a C++98/03 trick to disable copy ctor and assignment operator. in C++11 you can use = delete instead (also in public section) – Alexander Nov 22 '17 at 09:38
  • There is no such thing as the end of the class. What matters is the access specifier in which the members are declared. – CinCout Nov 22 '17 at 09:42

2 Answers2

11

This declares an overload for operator=. Overloading the operator would normally allow you to control how assignment expressions (a = b) are carried out.

In this case however, what's of interest is not the fact the operator is last, but that it's under the private access specifier. This means that outside code may not preform assignment (or copy construction for that matter, since the copy c'tor is there as well) of Component objects.

Code inside the class (in member functions) may assign and copy construct. But I would say that it's unlikely that it does. Marking those two special member functions private, and not defining them was the C++03 way of disabling copying for the class. One had to declare them to prevent the compiler from synthesizing the default copy constructor and assignment operator.

In modern C++, one may turn the "undefined symbol" error into a compile time error, by explicitly deleting those functions:

Component(const Component&) = delete;
Component& operator=(const Component&) = delete;
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Thank you. Would you recommend to always disable copying for a class ? – klaus Nov 22 '17 at 09:48
  • 2
    @klaus - This highly depends on the class. So I can't give absolute advice here. I would say however, that if you write a class that is heavy in logic, it may be a good idea to disable copying by default. You can always add it later if you need it. – StoryTeller - Unslander Monica Nov 22 '17 at 09:49
  • It's usually good to prevent copying (and, implicitly, moving) of polymorphic base classes, as such objects often have identity (can't just change the address), and/or [slicing](https://en.wikipedia.org/wiki/Object_slicing) is harmful for them. If your base class has at least one pure virtual (i.e. `virtual ... = 0;`) method, declaring the copy assignment operator as deleted is sufficient: `T &operator =(const T&) = delete;`. Otherwise, also declare the copy constructor as deleted. If you just want to prevent slicing, you can instead declare them as protected and define them as `= default`. – Arne Vogel Nov 22 '17 at 12:09
0

Placing declarations of the copy constructor and the copy assignment operator in the private section of the class makes objects of the class non-copyable.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335