user1559792
user1559792

Reputation: 377

Making a copy constructor

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

Answers (5)

PermanentGuest
PermanentGuest

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

Man of One Way
Man of One Way

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

Danil Speransky
Danil Speransky

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

Yochai Timmer
Yochai Timmer

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

Vaughn Cato
Vaughn Cato

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

Related Questions