Skip to main content
gamedev.net
🔒 Locked

Copy contructor

Started by kelaklub Jul 16, 2003 at 9:49 AM 12 replies 550+ views
Original Post
kelaklub
kelaklub
Can anyone explain to me in English what a copy constructor is, and what it is good for? Also a simple example would really help. Thank you
Sneftel
Sneftel
A copy constructor is a constructor that takes another object of its own class as its only argument, and uses that object as a "model" in constructing the object. The copy constructor is important in that it is automatically invoked when you pass an object by value into a function. The compiler will in most cases make a copy constructor for you, which simply copies over each member. (if some of the members are classes, their copy constructors will be invoked!) Rule of thumb: If you need a non-trivial destructor, you need a nontrivial copy constructor. And an assignment operator.

EDIT: oh, and here's your simple example:


class A
{
public:
A(const A &otherA) { a = otherA.a; } // copy constructor

private:
int a;
}


[edited by - sneftel on July 16, 2003 10:55:27 AM]
kelaklub
kelaklub
Someone told me the importance of a copy constructor is that it allows to pass an object of our class to any function by reference, is this true?
Oooh, also in
A(const A &otherA) 

what is the purpose of the
const 
keyword?
Thank you.

[edited by - kelaklub on July 16, 2003 11:08:27 AM]
BattleGuard
BattleGuard
A copy constructor is exactly what it tells you in english, a "copy constructor" . It makes another instance of a class, and then copies the information from one instance to another...

And the example is the same as ever, the simplest one...

BattleGuard



Only questions raise questions. Questions are raised by people, by curiousity, the gift of nature to all human beings. And curiosity is satisfied by answers, which in turn raise questions, which lead to answers. And this curiosity is what keeps SCIENCE alive...
Sneftel
Sneftel
quote:
Original post by kelaklub
Someone told me the importance of a copy constructor is that it allows to pass an object of our class to any function by reference, is this true?
No. The copy constructor is NOT invoked when you pass by reference, only by value.

quote:
what is the purpose of the
const  
keyword?


It basically means that you promise not to change otherA within the copy constructor (which would be rather odd). I''m not sure whether it''s required, but it''s good form. One thing that IS required is passing in otherA by reference, rather than by value. This is exactly BECAUSE the reference-passing doesn''t invoke the copy constructor. If you passed it in by value, you''d be asking the compiler to invoke the copy constructor during the copy constructor call--which would invoke the copy constructor again--ad infinitum. Bad craziness.
kelaklub
kelaklub
I have seen people do something like this
a(otherA.a)   
with copy constructors. Would anyone know what this is called and if it has any benefits? Thank you.


class A
{
public:
A(const A &otherA) : a(otherA.a){} // copy constructor

private:
int a;
};


[edited by - kelaklub on July 16, 2003 2:16:38 PM]

[edited by - kelaklub on July 16, 2003 5:10:50 PM]
Yanroy
Yanroy
I believe that is called a constructor initialization list, and it''s used to initialize the members of a class at the time of creation (as opposed to creating them and then assigning a value, as is done if you set them in the body of the constructor). It''s the difference between:

int a;
a = 0;

and

int a = 0;

I believe it is also the only way to initialize const member variables. I hope I''m right, you might want a verification from someone else or MSDN.

--------------------


You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming

You are unique. Just like everybody else.

"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor

Yanroy@usa.com

--------------------

You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming
You are unique. Just like everybody else.
"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor
JuNC
JuNC
Yep, that''s right. It''s also the (only) way to initialize reference members.
bslayerw
bslayerw
I believe it''s also the only way to initialize const members too.
bslayerw
bslayerw
In addition, it's a good idea to order your initialization list exactly as you have declared your members in the class.

like such:

class Fart
{
public:
Fart(int smellLevel,float maxdistanceCanTravel):
mSmellLevel(smellLevel),mMaxdistanceCanTravel(maxdistanceCanTravel) {}

private:
int mSmellLevel;
float mMaxdistanceCanTravel;
};


[edited by - bslayerw on July 16, 2003 5:40:11 PM]
zealouselixir
zealouselixir
... this is because, regardless of what order you specify your initializers in, the member data will be initialized in the order they are listed in the type definition.
[twitter]warrenm[/twitter]
kelaklub
kelaklub
This is all nice and good, but can anyone give me a really legitimate case for using a copy constructor, that starts out like, "If you don''t use a copy constructor it will be the end of the world because...."
Thank you
Sneftel
Sneftel
quote:
Original post by kelaklub
This is all nice and good, but can anyone give me a really legitimate case for using a copy constructor, that starts out like, "If you don't use a copy constructor it will be the end of the world because...."
Thank you

Behold: the end of the world.

class A
{
public:
A() : a(new int) { }
~A() { delete a; }
private:
int *a;
};

void foo(A someA) { }

int main()
{
A myA;
foo(someA);
}

Behold! When you construct your A, the integer pointer is initialized to an allocated block of memory. Then you call foo, which makes a copy of myA for use in the function (invoking the compiler-generated copy constructor). Then, when foo() ends, its copy is destroyed, thus freeing the memory. But wait! We still have myA around... when the program ends, we try to delete the SAME pointer again. A proper copy constructor would look like this:

A::A(const A &a) : a(new int(A.a)) { }

Which, rather than just bit-by-bit copying the class data (a "shallow copy"), would replicate the data structure (a "deep copy").


How appropriate. You fight like a cow.

[edited by - sneftel on July 17, 2003 10:42:31 AM]
kelaklub
kelaklub
I love the GameDev forums. Thank you all for your time and help.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.