# [SOLVED] Copy Constructors (C++)

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

## Recommended Posts

OK, I am using a prototype pattern for something, but I keep getting compiler errors when I try and implement the clone method.
virtual CEntity *clone()
{
return new CEntity(*this);
}
"note: candidates are: CEntity::CEntity(const CEntity&)" It stops complaining when I make my own copy constructor, but there is a bunch of fields in which I would have to manually assign, and none of them require new memory to be allocated ... so it seems a default copy constructor should be the right way to do it. The CEntity class is a sub class of ISceneNode which is a sub class of IUnknown (Irrlicht Engine stuff), I have looked at both these classes and it doesn't seem that there is anything wierd going on that would prevent me from using a copy constructor ... I must be missing something I never learned? [Edited by - AsOne on April 9, 2006 1:05:00 PM]

##### Share on other sites
correct me if I'm wrong but AFAIK if you provide one constructor, then the language standard is to not provide defaults for anything else. So if you are making your own constructors at all, there will be no default copy constructor, and thus, you would have to write your own.

If it works when you write your own, then why not just do that?

##### Share on other sites
It is not clear what the problem is because you didn't post the relevant code and you didn't even post the errors. The code below compiles. Try to figure out how it is different from yours.

class foo{	virtual foo * clone()	{		return new foo(*this);	}	int f;};class bar : public foo{	virtual foo * clone()	{		return new bar(*this);	}	int b;};void main(){	bar b;	foo * c = b.clone();	foo * x = &b;	foo * y = x->clone();}

##### Share on other sites
Thats the problem, I have no idea why it doesn't compile.
Quote:
 Original post by Morpheus011correct me if I'm wrong but AFAIK if you provide one constructor, then the language standard is to not provide defaults for anything else. So if you are making your own constructors at all, there will be no default copy constructor, and thus, you would have to write your own.

This worked.
class CCar{	public:		CCar(int wheels, int seats) : Wheels(wheels), Seats(seats)		{			}		virtual CCar *clone()		{			return new CCar(*this);		}		virtual void display()		{			cout << "Wheels: " << Wheels << endl;			cout << "Seats: " << Seats << endl;		}	private:		int Wheels;		int Seats;};class CSportsCar : CCar{	public:		CSportsCar(int wheels, int seats) : CCar(wheels, seats)		{					}		virtual CCar *clone()		{			return new CSportsCar(*this);		}};int main(){	CCar *car = 0;		CCar red(4, 6);	CSportsCar blue(2, 2);	car = red.clone();	car->display();		delete car;		car = blue.clone();	car->display();	delete car;        return 0;}

I get this error (in first post):
"note: candidates are: CEntity::CEntity(const CEntity&)"                        CEntity::CEntity(const irr::core::stringw&, irr::scene::IAnimatedMesh*, irr::IrrlichtDevice*)

... and the first part points to this line:
"return new CEntity(*this);"
... the second part points to the end of the constructor.

This is all the relevant code I can think of ...
CEntity::CEntity(    const stringw &name,    IAnimatedMesh *mesh,    IrrlichtDevice *device) : ISceneNode(0, device->getSceneManager())

Could there be something else affecting this? (super class?) I'm not sure what other code I could post.

EDIT: I thought maybe that if the class has pointers or something, it won't let you use the default copy constructor for safety purposes. But this compiled fine.
class Base{public:	Base(int *p) : P(p)	{	}	Base *clone()	{		return new Base(*this);	}	int *P;};int main(){	Base base1(new int);	*base1.P = 42;	Base *base2 = base1.clone();	cout << *base1.P << endl;	cout << *base2->P << endl;	delete base1.P;	delete base2;	return 0;}

##### Share on other sites
This is the only thing I can think of right now but maybe a parent of CEntity is hiding the copy constructor and that is why your getting errors and when you write your own, you are overriding the hidden one...

##### Share on other sites
Quote:
 Original post by Morpheus011correct me if I'm wrong but AFAIK if you provide one constructor, then the language standard is to not provide defaults for anything else.

The default constructor will not be generated. The copy constructor will.

##### Share on other sites
Quote:
 Original post by Adam HamiltonThis is the only thing I can think of right now but maybe a parent of CEntity is hiding the copy constructor and that is why your getting errors and when you write your own, you are overriding the hidden one...

ISceneNode only has one constructor, as well as IUnknown.

##### Share on other sites
try

virtual CEntity *clone() const
{
return new CEntity(*this);
}

##### Share on other sites
const correctness is certainly a good idea here, but it wont help with the compilation problem, in this case.

##### Share on other sites
CEntity::CEntity(const CEntity&) < I would assume that you dont have const when you defined it? As far as your other code, What line is bitching?

##### Share on other sites
Quote:
 Original post by AsOne"note: candidates are: CEntity::CEntity(const CEntity&)" CEntity::CEntity(const irr::core::stringw&, irr::scene::IAnimatedMesh*, irr::IrrlichtDevice*)

Does that second constructor have its second and third parameters declared with default values?

##### Share on other sites
Quote:
Original post by Bregma
Quote:
 Original post by AsOne"note: candidates are: CEntity::CEntity(const CEntity&)" CEntity::CEntity(const irr::core::stringw&, irr::scene::IAnimatedMesh*, irr::IrrlichtDevice*)

Does that second constructor have its second and third parameters declared with default values?

They do not, I just tried adding in default values though and the problem still persists :(

##### Share on other sites
OK this is wierd now ... I have made this a non-derived class, and have also removed the normal constructor, this happens ...
class CEntity // : public irr::scene::ISceneNode{ <------ "note: candidates are: CEntity::CEntity()"public:    /*    CEntity(        const irr::core::stringw &name,        irr::scene::IAnimatedMesh *mesh,        irr::IrrlichtDevice *device    );    */    virtual ~CEntity();               virtual CEntity *clone() const    {        return new CEntity(*this); <------ "note: CEntity::CEntity(const CEntity&)"    }    ...

I'm beginning to think I've done something really small, stupid, and obvious somewhere, I really want to delete every line of code in the entire project and just start over!

##### Share on other sites
Quote:
 Original post by AsOneOK this is wierd now ... I have made this a non-derived class, and have also removed the normal constructor, this happens ...

Hmm, I seem to recall seeing something like that when I was missing a semicolon or had an unmatched parenthesis somewheres lexically preceeding the error.

##### Share on other sites
Can you paste the full, actual code? It's hard to debug "..."

##### Share on other sites
This is entity.h, for anyone who uses Irrlicht, it's basically just like IAnimatedMeshSceneNode. I'm not sure if the implementation of this class would help in solving the problem.
#ifndef _ENTITY_H_#define _ENTITY_H_#include <irrlicht.h>class CEntity // : public irr::scene::ISceneNode{public:    /*    CEntity(        const irr::core::stringw &name,        irr::scene::IAnimatedMesh *mesh,        irr::IrrlichtDevice *device    );    */    virtual ~CEntity();               virtual CEntity *clone() const    {        return new CEntity(*this);    }         // functions    virtual int getCurrentFrame();    virtual void setCurrentFrame(int frame);    virtual bool setFrameLoop(int begin, int end);    virtual void OnPreRender();    virtual void render();    virtual void OnPostRender(unsigned int time);    virtual irr::video::SMaterial &getMaterial(int i);    virtual irr::scene::ISceneNode *getJointNode(const char *jointName);    virtual bool removeChild(irr::scene::ISceneNode *child);    virtual irr::core::aabbox3d<float> getCorrectedBoundingBox() const;        // inline    virtual inline void setAnimationSpeed(int framesPerSecond)    {        FramesPerSecond = framesPerSecond;    }    virtual inline void setLoopMode(bool looping)    {        Looping = looping;    }    inline unsigned int getMaterialCount() const    {        return Materials.size();    }    virtual inline const irr::core::aabbox3d<float> &getBoundingBox() const    {        return Mesh->getBoundingBox();    }protected:    inline unsigned int getTimeSinceLastFrame()    {        return TimeSinceLastFrame;    }private:    irr::ITimer *Timer;    irr::scene::IAnimatedMesh *Mesh;    unsigned int LastTime;    unsigned int TimeSinceLastFrame;    unsigned int BeginFrameTime;    int StartFrame;    int EndFrame;    int FramesPerSecond;    bool Looping;    irr::core::array<irr::video::SMaterial> Materials;    irr::core::array<irr::scene::IDummyTransformationSceneNode*> JointChildSceneNodes;    };#endif

The only errors in this file are the ones pointed out in my last post.

##### Share on other sites
try:

  CEntity& ref = *this;  return new CEntity(ref);

to see what happens...

or

  CEntity* p = new CEntity();  (*p) = (*this);  return p;

Just blindly guessing here.

##### Share on other sites
OK when I do this ...
CEntity &ref = *this;

It gives me the error ...
 error: invalid initialization of reference of type 'CEntity&' from expression of type 'const CEntity'

However, when I put const infront, it is fine with it, yet I still get the same error on the line as I always did...
return new CEntity(ref);
Wait, yeah the const thing is just becasue I declared the function as const.

Now trying the other way ...
We can clearly see that gcc does crack. This is actually what the error says ...
virtual CEntity *clone() const{    CEntity* p = new CEntity(); <--- "note: candidates are: CEntity::CEntity()"    (*p) = (*this);    return p;}

I find that hard to beleive as right above that function I declared a constructor ...
CEntity::CEntity() { }

I'm using Eclipse so I first thought maybe it's parsing gcc's output wrong, but it isn't. :(

It seems that all the other classes I derived from CEntity have the same strange error as I mentioned before, e.g.
class CItem : public CEntity
{ <--- note: candidates are: CItem::CItem(const CItem&)
... AHHHHHHHHH

##### Share on other sites
Uh.. "virtual inline" ? How does that work? heh

##### Share on other sites
Quote:
 Original post by AsOneI'm using Eclipse so I first thought maybe it's parsing gcc's output wrong, but it isn't.

What's the full GCC output in the console view? I've found that with some errors that have extra information on new lines (ie. the 'note:' lines) it will display the extra info as the error and not the error itself. The full output might have that extra peice of info needed to complete the puzzle.

Quote:
 Original post by RDragon1Uh.. "virtual inline" ? How does that work? heh

Actually the 'inline' is redundant, any functions that include the function body inside the class definition are automagically inlined. The inline part works because where ever the compiler *can* inline the function it will (eg. using the Entity class directly), but it will also generate an out-of-line version for when working with derived classes.

##### Share on other sites
YES!!! I looked at the console and it didn't give me much extra, but, I saw a few other errors pointing to another file (item.cpp), CItem is derived from CEntity, it turns out I forgot a comma inbetween two parameters when calling the CEntity constructor ... so it was saying a constructor didn't exist, thus, pointing me to entity.h (I knew it would be something dumb like this).

Why didn't the damn thing say "In this context?" like it usually does? Oh well, thanks for everyone for trying to help me out!