Sign in to follow this  

Clone method for inherited objects

This topic is 4534 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

I'm trying to write an OGL GUI system like so:
class COGLWindow
{
	char *window_name,	///< The name of the window (has to be unique)
	     *caption;		///< The caption for the window
	float x,		///< The x pos
	      y,		///< The y pos
	      height,		//< The height of the window
	      width;		///< The width of the window
	CColor window_color,	///< The main color of the window
	       text_color,	///< The color of the caption
	       cap_box_color;	///< For a window, the box at the top of the window that the caption is in

};

class COGLButton : public COGLWindow
{
	char* name;		///< The name of the button (unique)
	void (*func)(void);	///< A pointer to the function to call when the button is pressed

};



The data members on the heap are nothing more than c-style strings. I need to write a clone method because I'll have a series of windows held in a vector in a manager class, and for the buttons, and soon to be, other costrols, they will be added to lists inside a COGLWindow (eventually). Because Button inherits from Window, I was thinking something like this:
COGLWindow* COGLWindow::clone() const
{
	// create new COGLWindow object with copy constructor
}

COGLWindow* COGLWindow::clone(COGLWindow* o)
{
	o->window_name = strdup(this->window_name);
	o->caption = strdup(this->caption);
}



See, the first one is for use when a new COGLWindow object needs to be created, and the second one can be used when a control (in this case, Button) derived from COGLWindow is created. It seems a little inelegant, but is this a good way to do it? Or should I just clone all of COGLWindow's data members inside the COGLButton clone function?

Share this post


Link to post
Share on other sites
Your second "clone" looks like a thinly disguised (and backwards-ized) assignment operator. Also, why are you doing this? "Clone" methods are often useful, but "I'll have a series of windows held in a vector in a manager class" doesn't strike me as a reason to have one.

Share this post


Link to post
Share on other sites
If there isn't any special stuff that needs to be taken place in the cloning process, you can simply copy all of the data...
class COGLWindow {
...
virtual COGLWindow* clone();
};
COGLWindow* COGLWindow::clone() {
COGLWindow* winClone=new COGLWindow;
//No need for copy constructors here
memcpy(winClone,this,sizeof(COGLWindow);
return clone;
}
//And then...
class COGLButton : public COGLWindow() {
...
COGLWindow* clone();
};
COGLWindow* COGLButton::clone() {
COGLWindow* winCLone=new COGLButton;
memcpy(winClone,this,sizeof(COGLButton);
return winClone;
}
//You can also write a nifty little macro too (that looks somewhat odd)
#define WriteClone(cname) COGLWindow* cname::clone() { COGLWindow* winCLone=new cname; memcpy(winClone,this,sizeof(cname)); return winClone; }
//Of course, this cloning only creates a new object of that type... I'm not sure it'll be safe to clone to an existing object (memory leaking?)


This is the way I'd do it. Another way I do this with registering classes (instances) is have a macro create a function that will be registered in a list along with the other class information. This function simply creates a new instance of itself, and this allows me to create instances merely by calling them with ID's that were assigned to them during registration.

Share this post


Link to post
Share on other sites

As an alternative approach, after first worrying about whether you actual need to clone the object in the first place (see Sneftel's post). I'd suggest you stick with simple virtual clone methods that just calls the classes' copy constructors. And 'chain' your copy constructor calls, rather than your clone calls. Stucking with the copy constructs has the advantage that, if appropiate you can let the compiler generate them for you (however in your case you probably need to deep copy the char*)

Anyway enough talk and onto an example:

class COGLWindow
{
virtual COGLWindow* clone() const = 0;

// Base copy constructor
COGLWindow( const COGLWindow& p_Another );
};

class COGLButton : public COGLWindow
{
virtual COGLWindow* clone() const
{
return new COGLButton (*this);
}

// Derived copy constructor
COGLButton ( const COGLButton& p_Another );
};

// Base class copy constructor
COGLWindow::COGLWindow( const COGLWindow& p_Another )
:window_name(strdup(p_Another.window_name )),
caption (strdup(p_Another.caption )),
// ..snip..
{}


COGLButton::COGLButton ( const COGLButton& p_Another )
:COGLWindow(p_Another), // Invoke the base class copy constructor
name(strdup(p_Another.name)),
func(p_Another.func)
{}


Share this post


Link to post
Share on other sites
Just to add:

Since you're going to the trouble of defining a copy constructor, why not initialize the new copy's data in the initializer list?

Just another suggestion...


class Foo{

public:

Foo(const Foo &f) : _bar(f._bar) {}

private:

Bar *_bar;
};

Share this post


Link to post
Share on other sites

This topic is 4534 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.

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