C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problems with Clone idiom

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Edson Manoel
Guest





PostPosted: Thu Jul 21, 2005 10:41 am    Post subject: Problems with Clone idiom Reply with quote



I have a base class for owning/owned classes that only allow access
through shared pointers. I made it something like this (example):

class Base {
public:
typedef boost::shared_ptr<Base> SharedPtr;
typedef boost::weak_ptr<Base> WeakPtr;

protected:
WeakPtr weak_this; // weak pointer to this object (self-reference)
WeakPtr owner; // weak pointer to owner object
vector<SharedPtr> owned; // strong pointer to owned objected

Base() {}

public:
// reimplemented in each descendant

static inline SharedPtr Create() {
SharedPtr newBase(new Base);

// auto conversion from shared to weak
newBase->weak_this = newBase;

return newBase;
}

// same thing, but virtual member

virtual SharedPtr create() {
SharedPtr newBase(new Base);
newBase->weak_this = newBase;
return newBase;
}
};

The weak_this is needed because sometimes the object must return a
weak reference to itself, so that owned objects attach themselves to
it. E.g.:

....
void addObject(SharedPtr newOwned) {
newOwned.owner = weak_this;
owned.push_back(newOwned);
}
....

This is ok. I used the Create idiom because I must set the weak_this
pointer, and because only shared pointers are allowed. The problem
arrives when I need to build a copy constructor. Using the Clone idiom,
I would normally do:

....
public:

virtual SharedPtr clone() {
SharedPtr newBase(new Base(*this));
newBase->weak_this = newBase;
return newBase;
}

protected:

Base(const Base& other) {
// do the copying routined, e.g, copy children, etc...:
for (vector<Base>::iterator it = other.owned.begin(),
end = other.owned.end(); it != end; ++it) {

addObject(*it);
}
}
....

BUT the copy-constructor NEEDS the weak_this pointer to perform the
copy of the owned objects (in the addObject routine (newOwned.owner =
weak_this)) and I can't find a way to set it _before_ the copy
constructor in the clone() function. Also, the copy constructor is
needed (e.g., instead of an assign() function), because derived classes
will need to initialize the base copy constructor and also because
derived classes may need to initialize const parameters and/or
containers in the constructor initialization list.

What do you think? Are the create/clone idioms suited for this case,
or are them too limited? In this case, what could be done?

Thanks!


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Greg
Guest





PostPosted: Sat Jul 23, 2005 1:01 am    Post subject: Re: Problems with Clone idiom Reply with quote




Edson Manoel wrote:
....
Quote:
I have a base class for owning/owned classes that only allow access
through shared pointers. I made it something like this (example):

The problem arrives when I need to build a copy constructor. Using the Clone idiom,
I would normally do:

...
public:

virtual SharedPtr clone() {
SharedPtr newBase(new Base(*this));
newBase->weak_this = newBase;
return newBase;
}

...

BUT the copy-constructor NEEDS the weak_this pointer to perform the
copy of the owned objects (in the addObject routine (newOwned.owner =
weak_this)) and I can't find a way to set it _before_ the copy
constructor in the clone() function. Also, the copy constructor is
needed (e.g., instead of an assign() function), because derived classes
will need to initialize the base copy constructor and also because
derived classes may need to initialize const parameters and/or
containers in the constructor initialization list.

What do you think? Are the create/clone idioms suited for this case,
or are them too limited? In this case, what could be done?

Thanks!



I would suggest using initialization and assignment to create the
cloned pointer rather than using a single copy operation:

SharedPtr Base ::clone()
{
SharedPtr newBase = new Base;

newBase->weak_this = newBase;
newBase->assign(this);
return newBase;
}

The other step would be to declare an assign() method in Base and move
the code currently in its copy constructor there (and have the copy
constructor call assign, if desired). Note that you could define
operator= for Base, but the expression to perform the assignment,
something like:

*(newBase.get()) = *this;

looks a little unsettling; calling an explicit assign method instead
would be a more tasteful implementation.

Conceptually, this change just breaks the copy construction into its
two component operations. The finer granularity allows your
requirements to be met. It is also a slightly less efficient and less
compact approach, which is a good reason to favor copy construction in
most other cases.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.