boost :: shared_ptr并分配派生类

时间:2011-02-27 15:25:29

标签: c++ boost variable-assignment shared-ptr

假设DerivedClass来自BaseClass
以下是否有效?

boost::shared_ptr<BaseClass> a(new BaseClass());
boost::shared_ptr<DerivedClass> b(new DerivedClass());
a=b;

遵循此question,我了解现在a指向派生的和b点到基地(对吧?)

此外,现在如果我通过a调用一个函数,它会调用派生的实现吗?

3 个答案:

答案 0 :(得分:13)

...
a=b;

您正在重新分配到a,因此a b现在都会指向DerivedClass对象。 BaseClass对象将被销毁,因为此时它的引用计数将为零(由于a被重新分配以指向不同的对象)。

由于a现在指向DerivedClass对象,虚拟函数调用(在BaseClass中定义并在DerivedClass中覆盖)通过a将调用相应的DerivedClass中的成员函数。

ab都超出范围时,DerivedClass对象将被销毁。

如果您需要通过a访问特定于派生类的函数(例如,DerivedClass中的非虚函数),您可以使用:

boost::dynamic_pointer_cast<DerivedClass>(a)->SomeFunctionOnlyInDerivedClass();

当然这只是一个简洁的例子,展示了用法。在生产代码中,您几乎肯定会在取消引用指针之前测试成功转换为DerivedClass

答案 1 :(得分:4)

  

假设DerivedClass来自BaseClass。以下是否有效?

是。正如

没有任何问题
boost::shared_ptr<BaseClass> pbase(new DerivedClass());

(假设在两种情况下BaseClass都有一个虚拟析构函数。)智能指针的设计尽可能像普通指针一样,并提供与BaseClass* pbase = new DerivedClass();相同的行为,以及所有生命周期管理善。

  

根据这个问题,我了解现在a指向派生的和b点到基地(对吗?)

不,a和b都指向DerivedClass实例。链接文章引用的交换发生在 operator = 内的临时对象上。当该临时对象超出范围时,将删除BaseClass实例。

  

此外,现在如果我通过a调用一个函数,它会调用派生的实现吗?

是。如果你看一下 operator-&gt; 的实现,它所做的就是返回指向基本 operator-&gt; 的指针:

T * operator-> () const // never throws
{
    BOOST_ASSERT(px != 0);
    return px;
}

这样行为与普通指针相同。

答案 2 :(得分:3)

当做a = b时,你告诉a指向对象b也指向。所以你调用的所有方法,你调用对象b的BaseClass部分都指向。

因此,如果它包含在DerviedClass中覆盖的虚方法,则会调用覆盖的版本。