【问题标题】:boost::shared_ptr and assigning derived classesboost::shared_ptr 和分配派生类
【发布时间】:2011-02-27 15:25:29
【问题描述】:

假设DerivedClass 派生自BaseClass
下面的工作吗?

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

按照question,我知道现在a 指向派生,b 指向基(对吗?)

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

【问题讨论】:

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


    【解决方案1】:
    ...
    a=b;
    

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

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

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

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

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

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

    【讨论】:

    • static_pointer_cast 不是也可以工作,因此不是在DerivedClass 中调用非虚拟函数的首选方式吗? boost::static_pointer_cast&lt;DerivedClass&gt;(a)-&gt;SomeFunctionOnlyInDerivedClass();
    【解决方案2】:

    假设DerivedClass 派生自BaseClass。下面的工作吗?

    是的。就像没有什么问题一样

    boost::shared_ptr<BaseClass> pbase(new DerivedClass());
    

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

    按照这个问题,我知道现在a 指向派生,b 指向基(对吗?)

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

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

    是的。如果您查看 operator-> 的实现,它所做的只是返回要调用基本 operator-> 的指针:

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

    因此行为与普通指针相同。

    【讨论】:

      【解决方案3】:

      在执行 a=b 时,您告诉 a 指向 b 也指向的对象。所以你调用的所有方法,你调用的都是对象b指向的BaseClass部分。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-04
        • 2013-02-06
        • 2011-04-14
        • 2013-08-16
        相关资源
        最近更新 更多