• 13
• 15
• 27
• 9
• 9

# Copy constructor (i.e. Object(const Object& copy))

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

## Recommended Posts

I have a question about using the copy constructor in C++. I have defined one like so (using class Object as an example):
Object(const Object& copy)
and i can copy an object like this:
Object* clone() { return new Object(*this); }
But when i pass a non-constant member object i get compiler errors and i have to cast:
newObject = Object((const Object&)objToCopy);
Is this the correct way to do it? And if so, why? thanks

##### Share on other sites
Post a minimal, but complete, code sample that demonstrates your problem.

##### Share on other sites
This may not solve your problem but can I just remark that your clone() method should be const, since it doesn't modify the instance it is invoked on?

class Object{public:    Object( const Object& copy );    virtual Object* clone() const { return new Object(*this); }    // ...};

P.S. Also, in cases where you need to cast types, avoid using C-style casts and use the C++ cast operators instead. The example you gave is unusual, since it should rarely be necessary to add constness to a reference / pointer but anyway, using the C++ const_cast operator, your example would look like this.

newObject = new Object( const_cast < const Object& > ( objToCopy ) );

[Edited by - Red Ant on May 18, 2009 6:56:37 PM]

##### Share on other sites
Quote:
 Original post by SiCranePost a minimal, but complete, code sample that demonstrates your problem.

I was going to post my code to give an example of the context in which the copy-constructor is being used, but i'm at work now so i can't copy/paste. This is from memory:
(Actually, by writing it down i think i have found a solution. But keep reading anyway [smile])
class Weapon {public:    Ammo* ammo;    ...    /* Game has a list of all weapons. When a player buys a weapon, it will       be copied from the list into the player's list of weapons. It is a       deep copy so it can be modified by upgrades */    Weapon(const Weapon& copy);    virtual Weapon* clone() = 0;  // @Red Ant: it might be const, i can't remember};class RocketLauncher : public Weapon {public:    Weapon* clone() { return new RocketLauncher(*this); }}// When player buys a weapon i will do this:player->weapon = selectedWeapon->clone();/* I do a similar thing with ammo. Each weapon will have an Ammo object which   represents the ammo it fires. When fired, a new Ammo object will be created   to be shot out of the gun in what ever way it does */class Ammo {public:    float damage;   // How much damage it will do to a player    Image* image;   // Image to draw (e.g. rocket, grenade, bullet)    Weapon(const Weapon& copy);    virtual Ammo* clone() = 0;};class ProjectileAmmo : public Ammo, public PhysicsObject {public:    ProjectileAmmo (const ProjectileAmmo& copy) :        Ammo(copy), PhysicsObject() {}    virtual Ammo* clone() { return new ProjectileAmmo(*this); }};/**** Ok, here is where i am having trouble ****/void Weapon::fireProjectile() {    // I could just use clone() here, lol    ProjectileAmmo* ammoFired = new ProjectileAmmo((const ProjectileAmmo&)this->ammo);    ...    // fire the ammo, etc}

So basically, in the last function i am trying to create a copy of the Ammo object that the Weapon has. I can just use the clone() function to do that (i don't know why i didn't think of that last night when i was writing it). But since ProjectileAmmo is a generalisation of Ammo, why do i need the cast in the first place?

##### Share on other sites
Because a ProjectileAmmo is an Ammo, but an Ammo isn't necessarily a ProjectileAmmo.

##### Share on other sites
edit: never mind. posted while examples etc were being written

1. what is the advantage of
Object *newObj = oldObj.clone();

over
Object *newObj = new Object(oldObj);

??

2.
newObject = Object((const Object&)objToCopy);

this syntax is illegal.
you either want
Object newObject(objToCopy);// or Object* newObject = new Object(objToCopy);

both of which work fine.

##### Share on other sites
Quote:
 1. what is the advantage ofObject *newObj = oldObj.clone();overObject *newObj = new Object(oldObj);

Polymorphism. The former can return anything derived from Object (depending on the dynamic type of "oldObj", which I am assuming to be a reference). The latter will only create new Objects.

##### Share on other sites
Quote:
 Original post by ChaosEngine2.newObject = Object((const Object&)objToCopy);this syntax is illegal.you either wantObject newObject(objToCopy);// or Object* newObject = new Object(objToCopy);both of which work fine.

Damn! Yeah, I didn't even catch that and even replicated the mistake in my post. *hangs head in shame*

##### Share on other sites
Quote:
 Original post by SiCraneBecause a ProjectileAmmo is an Ammo, but an Ammo isn't necessarily a ProjectileAmmo.

Oh, yeah. But why do i need the cast to const-ness? Why can't i just do:
ProjectileAmmo* ammoFired = new ProjectileAmmo(*ammo);

like in the clone() function? ammo isn't const but i thought the const in the copy-constructor just meant that the copy-constructor couldn't modify the value.

##### Share on other sites
Quote:
Original post by rip-off
Quote:
 1. what is the advantage ofObject *newObj = oldObj.clone();overObject *newObj = new Object(oldObj);

Polymorphism. The former can return anything derived from Object (depending on the dynamic type of "oldObj", which I am assuming to be a reference). The latter will only create new Objects.

You are, of course, correct. There was no virtual in the OPs example, so I didn't think of polymorphism.