-1

I used the code below to test the behaviour of copy assignment operator:

#include <iostream>
using namespace std;

int group_number = 10; // Global

class Player {
public:
  explicit Player(const int &g): group(g)
  {
  }

  Player& operator=(const Player& rhs)
  {
      cout << "Copy assignment operator called " << endl;
      return *this;
  }

  void set_stamina(int i) {stamina = i; }
  int  get_stamina()      {return stamina; }
  const int &get_group()  const { return group; }

protected:
  const int &group;

private:
  int stamina;
}; // End of Player class

class Round {
public:
  Round(const Player &p)
  {
    main_player = &p;
  }

  const Player &get_main_player() const
  {
    return *main_player;
  }

protected:
  const Player *main_player;
}; // End of Round class

// Test code
int main()
{
  Player p1(group_number);
  Round r(p1);
  p1.set_stamina(100);

  // Add player2 in the same group as p1
  Player p2(group_number);
  p2 = r.get_main_player();
  cout << "This is p1's stamina: "    << p1.get_stamina()
       << ", and p1's group number: " << p1.get_group() << endl;;
  cout << "This is p2's stamina: "    << p2.get_stamina()
       << ", and p2's group number: " << p2.get_group() << endl;;

  return 0;
}

I expected both p1 and p2 have the same value of stamina. But the output shows that p2's stamina is different from p1's

Copy assignment operator called
This is p1's stamina: 100, and p1's group number: 10
This is p2's stamina: 241098768, and p2's group number: 10

Why the copy assignment operator not copying the value of p1's stamina to p2?

8
  • 7
    You've defined a user defined assignment operator in which you explicitely do not copy the stamina. So by definition this wont work. Just copy over the stamina if thats what you require. Commented Jan 18, 2022 at 15:16
  • Your code has undefined behavior. Just add stamina = rhs.stamina; inside the copy assignment operator and you'll get your expected output. Commented Jan 18, 2022 at 15:21
  • but why group gets copied but stamina not? Commented Jan 18, 2022 at 15:25
  • 1
    What evidence do you have that group was copied? Your code did not copy it. Simply it was initialized to the same value (or as a const ref to the same integer variable) and the copy operator did not change it. Anyway as group is declared as a const ref, you cannot change it... Commented Jan 18, 2022 at 15:28
  • 1
    On a related note, references make very bad members. Assign a new value to group_number after this code, then examine both objects again. Commented Jan 18, 2022 at 15:33

2 Answers 2

2

You have not copied the data member stamina inside the copy assignment operator. So just add stamina = rhs.stamina; inside the copy assignment operator and you'll get your expected output. So the modified definition of operator= looks like:

Player& operator=(const Player& rhs)
  {
      cout << "Copy assignment operator called " << endl;
      stamina = rhs.stamina; //ADDED THIS 
      return *this;
  }

Also, note that in your original code snippet, since the data member stamina is not initilized and so it has indeterminate value. Using this uninitialized variable(which you do when you wrote p2.get_stamina();) is undefined behavior.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.

So the output that you're seeing is a result of undefined behavior. And as i said don't rely on the output of a program that has UB.

So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.

To solve this more serious problem just use in-class initilaizer for data member stamina.

class Player {
    //other members here
private:
  int stamina = 0; //USE IN-CLASS INITIALIZER
};

1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

Sign up to request clarification or add additional context in comments.

Comments

1

Why the copy assignment operator not copying the value of p1's stamina to p2?

You defined the operator. You don't copy any values in your definition of the operator, so no values are being copied.

You could assign the member like this:

stamina = rhs.stamina;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.