peer_2_peer_2
peer_2_peer_2

Reputation: 135

What happens when a class is set by reference

I'm moving from using the C-style of setting values for structs in functions via ptrs to C++ style of using object references. What I don't understand is, when I pass an object by reference, and then set it to a new object, how is the data set? I would have thought it was the copy constructor, but it doesn't seem to have any effect.

Example

#include <iostream>

using namespace std;

class Profile{
    public:
  string name;
  int age;
  Profile();
  ~Profile();
  Profile( const Profile &profile); 
};
Profile::Profile(){
    name = "BILLY BOB";
    age = 234;
}
Profile::~Profile(){}
Profile::Profile( const Profile &profile){
    cout << "COPY CONSTRUCTOR" << endl;
}

void GetProfile(Profile &profile){
    cout << &profile << endl;
    Profile p;
    // what's going on here?
    profile = p; 
}

int main()
{
    Profile p;
    p.name = "MIKE";
    p.age = 55;
    cout << p.name << endl;
    cout << p.age << endl;
    cout << &p << endl;
    GetProfile(p);
    cout << p.name << endl;
    cout << p.age << endl;
    return 0;
}

Everything is set properly, I just don't understand how.

Upvotes: 1

Views: 90

Answers (2)

ichramm
ichramm

Reputation: 6642

I would like to start by stating that the copy constructor is incorrect: The variables are not being initialized, therefore, it will not work the way you think it will work:

You should fix it, like this:

Profile::Profile(const Profile &profile)
: name(profile.name) // copy name
, age(profile.age) // copy age
{
    cout << "COPY CONSTRUCTOR" << endl;
    age = age/3; // this variable was used without being initialized
}

Now, to the issue:

The variable profile is already initialized, it will not be created again! When you use the assignment operator, the compiler will call, well, the assignment operator!

If an implementation is not provided, the compiler will generate one for you, have in mind that these methods should be implemented only if needed, according to the rule of 3/5/0.

Finally, the assignment operator should look like this:

Profile& operator=(const Profile &other) {
    this->name = other.name;
    this->age = other.age;
    return *this;
}

Upvotes: 0

Radosław Cybulski
Radosław Cybulski

Reputation: 2992

Assignment is happening. Try adding:

class Profile{
    public:
  string name;
  int age;
  Profile();
  ~Profile();
  Profile( const Profile &profile); 
  Profile &operator = (const Profile &);
};
Profile &Profile::operator = ( const Profile &profile){
    cout << "COPY ASSIGNMENT" << endl;
    age = age/3;
    return *this;
}

You wrote profile = p;. profile is a variable, to which some value will be assigned. In that case operator = will be executed on this variable, so class user could modify, how class values are assigned. You're free (as class writer) to do, whatever you want in this assignment operator. You don't have to do the same, as in copy constructor (although you should, as users will be suprised). And you don't even have to return *this, although once again if you dont, then your users will be suprised.

EDIT: in c++11 and future there's also move constructor / assignment:

class Profile{
    public:
  string name;
  int age;
  Profile();
  ~Profile();
  Profile( const Profile &profile); 
  Profile( Profile &&profile); 
  Profile &operator = (const Profile &);
  Profile &operator = (Profile &&);
};
Profile &Profile::operator = ( Profile &&profile){
    cout << "COPY ASSIGNMENT" << endl;
    age = age/3;
    return *this;
}

those are going to be "fired", when you will assign (or create) from temporary variable. For example:

Profile p;
p = Profile(...);

in a second line you get temporary Profile value, which move assignment hopefully might somehow utilize, since that value is going to be destroyed anyway. So for example strings will pass it's content instead of copying, and so on.

Upvotes: 3

Related Questions