 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Edson Manoel Guest
|
Posted: Thu Jul 21, 2005 10:41 am Post subject: Problems with Clone idiom |
|
|
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
|
Posted: Sat Jul 23, 2005 1:01 am Post subject: Re: Problems with Clone idiom |
|
|
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 |
|
 |
|
|
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
|
|