Reputation: 135
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
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
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