Clone method for inherited objects

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

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 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 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 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 constructorCOGLWindow::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 on other sites

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;};

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• Forum Statistics

• Total Topics
633298
• Total Posts
3011249
• Who's Online (See full list)

There are no registered users currently online

×