2

I'm new to C++ and just learned about overloading operators. I'm confused because it seems like I can assign one object to another without having to overload the "=" operator. Take this code as example:

class process
{
  int size;
  
public:
  process(int s)
  {
    size = s;
  }
  ~process();

  int getSize()
  {
    return size;
  }
  
};

int main()
{
  process p1(2);
  process p2(3);
  p1 = p2;
  std::cout << p1.getSize() << "\n";
}

The output is:

3

As you can see, the info from the process class "p2" were copied to "p1", but I haven't overloaded the "=" operator. Why is this happening? Is there any place where I can have some concrete info about what C++ did for this to happen? Thanks.

Float07
  • 314
  • 2
  • 12
  • Tangential, but good reading: [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – user4581301 Jul 01 '20 at 03:30

1 Answers1

6

Why can I assign one object to another without overloading the “=” operator?

Because classes have an implicitly generated copy (and move) assignment operator.

Is there any place where I can have some concrete info about what C++ did for this to happen?

Authorative source of info is the standard document.

Books have also been written about C++.


But then why would I want to overload the "=" operator?

There is no reason to want to overload assignment operator of your example class.

In general, you may want to overload because

  • The assignment operator generated by the compiler cannot read your mind and do what you want it to do. it does exactly one thing, and if that is not what you want, then you need to define your own. If you follow best practices, then most often the implicitly generated assignment operator does do what you want.

  • You may sometimes want to be able to assign other types.

  • Sometimes the implicitly generated operator is deleted, such as when there are non-assignable members. In such case, you may define your own if you know what the operator should do.


P.S. The compiler also implicitly generates the destructor. You don't need to define a destructor for your class.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • But then why would I want to overload the "=" operator? – Float07 Jul 01 '20 at 03:27
  • [wikipedia](https://en.wikipedia.org/wiki/Special_member_functions) also has a great article on special member function generation. Feel free to steal the link for your answer – alter_igel Jul 01 '20 at 03:28
  • 1
    @Float07 Because the compiler doesn't know what you really want to do sometimes. Perfect examples are the [Rules of Three and Five](https://en.cppreference.com/w/cpp/language/rule_of_three) – user4581301 Jul 01 '20 at 03:29
  • @Float07 you should only overload `operator=` if you need it to do something that the default version doesn't. If you use standard library types and stay away from raw owning pointers, then you essentially never need to do so. – alter_igel Jul 01 '20 at 03:29
  • E.g. consider `std::vector`. The actual `std::vector` object is just a pointer to some storage plus other control data. The default `operator=` would just copy that *reference* to your data, but the actual `operator=` actually assigns/constructs/destroys the underlying objects, giving `std::vector` value semantics instead of reference semantics. – HTNW Jul 01 '20 at 03:41
  • If you follow best practices, then most often the implicitly generated assignment operator does do what you want. I disagree, in more complex programs you would want to increase or keep a count of your objects, so you would want to increase the number of that object after assigning so if your count is currently 1, after doing Object a b; the count should be incremented to 2. – Yunfei Chen Jul 01 '20 at 04:10
  • 2
    @YunfeiChen 1. I can't imagine a case where that would be useful 2. Assignment operator doesn't create a new object. – eerorika Jul 01 '20 at 09:51
  • 1
    @YunfeiChen see the [Rule of Zero](https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_zero) for a major best practice here. TL;DR version distills down to "Code that doesn't exist has no bugs, so don't write anything you don't have to." If you have to manually count the number of objects in play, you've over-complicated and instead should be embracing [RAII](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii). – user4581301 Jul 01 '20 at 15:03
  • If you need the counter, instead of adding counting functionality to classes, you should have one class that counts itself that other classes use.The exact mechanics (probably when a counter object is constructed, the count goes up and when it's destroyed the count goes down) are encapsulated by the counter class following the ideology that resource management should be kept as close to the resource, the count, as possible. Containing objects need not care how or why the count changes, they just trust that it does and observe the Rule of Zero. – user4581301 Jul 01 '20 at 15:08