boost::shared_ptr and assigning derived classes
Assume DerivedClass
is derived from BaseClass
boost::shared_ptr<BaseClass> a(new 开发者_开发百科BaseClass());
boost::shared_ptr<DerivedClass> b(new DerivedClass());
a=b;
Following this question, I understand that now a
points to the derived and b
points to the base (right?)
Also, now if I call a function via a
would it call the derived implementation?
...
a=b;
You are reassigning to a
and therefore a
and b
would now both point to the DerivedClass
object. The BaseClass
object would be destroyed, since its reference count would be zero at this point (by virtue of a
being reasigned to point to a different object).
Since a
now points to a DerivedClass
object, virtual function calls (defined in BaseClass
and overriden in DerivedClass
) via a
would call the corresponding member functions in DerivedClass
.
When both a
and b
go out of scope, the DerivedClass
object would be destroyed.
If you need to access functions specific to the derived class via a
(e.g., non-virtual functions in DerivedClass
), you can use:
boost::dynamic_pointer_cast<DerivedClass>(a)->SomeFunctionOnlyInDerivedClass();
Of course this is just a terse example that shows usage. In production code, you would almost certainly test for a successful cast to the DerivedClass
, before dereferencing the pointer.
Assume
DerivedClass
is derived fromBaseClass
. Would the following work?
Yes. Just as there's nothing wrong with
boost::shared_ptr<BaseClass> pbase(new DerivedClass());
(Assuming in both cases that BaseClass has a virtual destructor.) The smart pointer is designed to behave like a plain pointer as much as possible, and provide the same behaviour as BaseClass* pbase = new DerivedClass();
, plus all that lifetime-management goodness.
Following this question, I understand that now
a
points to the derived andb
points to the base (right?)
No, a and b would both point to the DerivedClass instance. The swap that the linked article refers to happens on a temporary object inside operator=. When that temporary object goes out of scope, the BaseClass instance would be deleted.
Also, now if I call a function via
a
would it call the derived implementation?
Yes. If you look at the implementation of operator->, all it does is return the pointer which the fundamental operator-> is to be called on:
T * operator-> () const // never throws
{
BOOST_ASSERT(px != 0);
return px;
}
so that the behaviour is the same as a plain pointer.
When doing a=b you tell a to point to the object b also points to. So all methods you call, you call on the BaseClass part of the object b points to.
So if it contains a virtual method that is overwritten in DerviedClass, the the overwritten version is called.
精彩评论