Reputation: 377
I have a question about copy constructors. I see these examples on internet. the first one says without copy constructors if you change something on student2 the same field change also on student1. but on the second examples changes on student2 doesn't affect student1 because of copy constructor. I didn't understand how this happened, what actually copy constructors do here? (sorry for bad english) (thanks for all answers :) )
class MITStudent {
public:
int studentID;
char *name;
MITStudent() {
studentID = 0;
name = "";
}
};
int main() {
MITStudent student1;
student1.studentID = 98;
char n[] = "foo";
student1.name = n;
MITStudent student2 = student1;
student2.name[0] = 'b';
cout << student1.name; // boo
}
second one
class MITStudent {
public:
int studentID;
char *name;
MITStudent() {
studentID = 0;
name = "";
}
MITStudent(MITStudent &o) {
name = my_strdup(o.name);
studentID = o.studentID;
}
};
int main() {
MITStudent student1;
student1.studentID = 98;
char n[] = "foo";
student1.name = n;
MITStudent student2 = student1;
student2.name[0] = 'b';
cout << student1.name; // foo
}
Upvotes: 3
Views: 2204
Reputation: 5331
In a typical case, with a default copy constructor, the situation will be as given in the left side of the picture!. A copy constructor is implemented to avoid this and have a scenario as given in the right side.
However, usually this happens with pointer members. So, avoid them as much as possible. Use them only if you 1. Can create a member only after a later stage than the constructor 2. Want to destroy a member and recreate it 3. Want to make the member outlive the object.
In your case, it doesn't look like you are in any of the above scenarios. In this case, you can safely use nice string object and you don't have to worry about any dangling pointers.
Upvotes: 0
Reputation: 3980
In the first example the copy constructor is implicitly created by the compiler.
It basically looks like this:
MITStudent(const MITStudent &o) {
name = o.name;
studentID = o.studentID;
}
It only copies the pointer name
.
In the second example, the copy constructor is explicitly created and copies the data that name
is pointing to. This way, name
in student2
is pointing to the copied data.
Upvotes: 0
Reputation: 30453
If there is no MITStudent(MITStudent &o)
it is just copy values of all fields. So if there is a pointer field then both fields will contain the same adress.
Upvotes: 0
Reputation: 49251
Default copy constructors are generated automatically if you don't specify your own.
They just copy all the class'es members by value to the new class.
The problem usually arises when you have pointers as class members.
The default copy constructor will just copy the address that his held by the pointer.
This means that both the original and the copied class now point at the same object.
That's exactly what happens in your example with the char*
"string"...
BTW, as a thumb rule.. if you have a class that has pointers as members, create a custom copy constructor.
Upvotes: 4
Reputation: 64308
A copy constructor is automatically generated for you if you don't create one. The automatically generated copy constructor will just copy the pointer to the name and not the name itself. By creating your own constructor, you can manually copy the whole name, and not just the pointer.
In actual code, you would want to use something like std::string instead of a char* though. This way, the automatically generated copy constructor will do what you want, and you won't need to write your own.
Upvotes: 0