• Advertisement
Sign in to follow this  

Copy Constructor Help

This topic is 4651 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im learning C++ atm, but I am confused with the idea of a Copy Constructor. Can anyone explain it, and why I would want to use one?

Share this post


Link to post
Share on other sites
Advertisement
A copy constructor lets you do custom operations when an object gets copied. You can do some really powerful things with it.

The main reason for them is to ensure that copies of pointers are handled correctly to prevent hanging pointers and double-deletion and so on. For example:


class Foo
{
// a pointer to an integer
int* myval;
public:
// when we construct, we create an integer
Foo() { myval = new int; }
// when we destruct, we must delete what we created
~Foo() { delete myval; }

// now, if someone were to make a copy of this object they
// would get a copy of myval - a copy of the pointer, not the
// object itself. Thus when both the copy and original are
// deconstructed, the integer is deleted twice. This is bad.
// Thus, we implement our own, custom copy behaviour to ensure
// that we're not going to cause such a double-deletion situation:
Foo(const Foo& f)
{
// make our *own* integer that we own and will delete ourselves
myval = new int;
// because we're copying, we probably still want to copy the value
*myval = *(f.myval);
}
};

Share this post


Link to post
Share on other sites
Copy Constructors are used when you're creating a copy of something. E.g.:

class foo {};

foo a; //calls the default constructor
foo b = a; //calls the copy constructor
foo c ( b ); //calls the copy constructor
foo d; //calls the default constructor
d = c; //calls the assignment operator (operator=)


By default, classes have an automatic copy constructor generated, so that this works:

class foo {
public:
int bar;
};

foo a;
a.bar = 3;
foo b = a; //copy constructor
assert( b.bar == 3 );

Now, problems can arise when you have a pointer, since instead of copying the pointed to value, it just copys the address... e.g.:

class foo {
public:
int * bar;
};

foo a;
a.bar = new int;
foo b = a; //a.bar and b.bar point to the same int
delete a.bar;
*(b.bar) = 3; //oops, we deleted the int, who knows what this does!!!

This kind of problem can be solved with a copy constructor:

class foo {
public:
int * bar;
foo( const foo & other ) //copy constructor
{
if (other.bar)
{
bar = new int;
*bar = *(other.bar);
}
}
};

Then, when we do:

foo a;
a.bar = new int;
foo b = a; //b.bar gets it's own int.
delete a.bar;
*(b.bar) = 3; //OK, we only deleted a.bar, b.bar pointed to something else
delete b.bar;

Sidenote: I'm being very horrible in encapsulation, by doing none. Don't code like this :-p.

Note that you will most likely have to implement your own operator= as well, because we have the original problem if we do:

foo a;
a.bar = new int;
foo b;
b = a; //a.bar and b.bar point to the same int
delete a.bar;
*(b.bar) = 3; //oops, we deleted the int, who knows what this does!!!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement