开发者

boost::shared_ptr and assigning derived classes

开发者 https://www.devze.com 2023-02-13 13:41 出处:网络
Assume DerivedClass is derived from BaseClass Would the following work? boost::shared_ptr<BaseClass> a(new 开发者_开发百科BaseClass());

Assume DerivedClass is derived from BaseClass

Would the following work?

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 from BaseClass. 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 and b 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消