Suppose that I have
- three classes
P,C1,C2, - composition (strong aggregation) relations between
P <>- C1andP <>- C2, i.e. every instance ofPcontains an instance ofC1and an instance ofC2, which are destroyed when the parentPinstance is destroyed. - an association relation between instances of
C1andC2(not necessarily between children of the sameP).
To implement this, in C++ I normally
- define three classes
P,C1,C2, - define two member variables of
Pof typeboost::shared_ptr<C1>,boost::shared_ptr<C2>, and initialize them with newly created objects inP's constructor, - implement the relation between
C1andC2using aboost::weak_ptr<C2>member variable inC1and aboost::weak_ptr<C1>member variable inC2that can be set later via appropriate methods, when the relation is established.
Now, I also would like to have a link from each C1 and C2 object to its P parent object. What is a good way to implement this?
My current idea is to use a simple constant raw pointer (P * const) that is set from the constructor of P (which, in turn, calls the constructors of C1 and C2), i.e. something like:
class C1
{
public:
C1(P * const p, ...)
: paren(p)
{
...
}
private:
P * const parent;
...
};
class P
{
public:
P(...)
: childC1(new C1(this, ...))
...
{
...
}
private:
boost::shared_ptr<C1> childC1;
...
};
Honestly I see no risk in using a private constant raw pointer in this way but I know that raw pointers are often frowned upon in C++ so I was wondering if there is an alternative solution.
1 Answer 1
Pointers create headaches when you use them to manage dynamically allocated resources. In this case, however, a pointer is a simple "backlink" to the parent, and it cannot be changed during the lifetime of a child object (i.e. there's no re-parenting). This is a good solution that helps you keep things simple.
-
I had thought about using a weak pointer from child to parent, but in order to initialize it I need to give the child a shared pointer pointing to the parent. But the parent does not have a shared pointer to itself so I discarded this solution.Giorgio– Giorgio2012年10月03日 14:53:22 +00:00Commented Oct 3, 2012 at 14:53
-
@Giorgio A weak pointer would probably be an overkill in this situation, because the parent fully owns its children. Since children get deleted along with the parent, there is little reason to give them weak pointers.Sergey Kalinichenko– Sergey Kalinichenko2012年10月03日 14:56:16 +00:00Commented Oct 3, 2012 at 14:56
-
The fact that a weak pointer would be an overkill is not the only problem. To construct a boost::weak_ptr<P> I need to pass it a boost::shared_ptr<P>: how can I get this boost::shared_ptr<P> within the constructor of P?Giorgio– Giorgio2012年10月03日 15:09:06 +00:00Commented Oct 3, 2012 at 15:09
-
This is the main thing enable_shared_from_this is good for: it allows the parent to recover a shared_ptr from its this pointer within the constructor call.Dennis– Dennis2018年01月17日 16:16:23 +00:00Commented Jan 17, 2018 at 16:16