Sign in to follow this  
Gink

Copy Constructor Help

Recommended Posts

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this