A wrong usage of boost.enable_shared_from_this

A wrong program in boost-user mail list:


#include <iostream>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

// Inheritance Layout
//
// boost::enable_shared_from_this<T>
// ^
// |
// Base --------> IBase
// ^
// |
// Derived -----> IDerived


class IBase
{
public:
virtual ~IBase(){}
virtual void hello(void) = 0;
};

class Base : public IBase, public boost::enable_shared_from_this<Base>
{
public:
~Base(void){}

void hello(void)
{
std::cout << "Hello" << std::endl;
}
};

class IDerived
{
public:
virtual boost::shared_ptr<Base> root(void) = 0;
virtual boost::shared_ptr<IBase> root2(void) = 0;
};

class Derived : public IDerived, public Base
{
public:
~Derived(void){}

virtual boost::shared_ptr<Base> root(void)
{
return shared_from_this();
}

virtual boost::shared_ptr<IBase> root2(void)
{
return shared_from_this();
}
};

int main(int argc, char* argv[])
{
boost::shared_ptr<IDerived> c(new Derived());
boost::shared_ptr<IBase> d = c->root2();
boost::shared_ptr<Base> e = c->root();
std::cout << c.use_count() << std::endl;


boost::shared_ptr<IDerived> l ((IDerived*)new Derived);
boost::shared_ptr<Base> n = l->root();//here throws an exception
boost::shared_ptr<IBase> m = l->root2();//also here

std::cout << m.use_count() << std::endl;

return 0;
}



Totally, For enable_shared_from_this to work, the static type of the pointer passed to the shared_ptr constructor must inherit from enable_shared_from_this.


shared_ptr's constructor in line 168 calls 'boost::detail::sp_enable_shared_from_this( pn, p, p );'.

'boost::shared_ptr<IDerived> c(new Derived());' is dispatched to 'sp_enable_shared_from_this' in line 86. pay attension to the second parameter, it can accept all types that inherit 'enable_shared_from_this<T>', so does 'Derived*'.

While, 'boost::shared_ptr<IDerived> c((IDerived*)new Derived());' is dispatched to 'sp_enable_shared_from_this' in line 111, bacause the static type IDerived* has nothing to do with 'enable_shared_from_this<T>' and can not be implicitly converted to 'enable_shared_from_this<T>'.

Then check out the difference between the two 'sp_enable_shared_from_this'. It is obvious that the second usage shall cause a BOOST_ASSERT failed in 'enable_shared_from_this::shared_from_this', so an exception is raised.

However, I think the root reason is not the language nor boost, but the design of class IDerived. Its root and root1 seem a little bit irrational because there is not direct relationship between IDerived and Base(IBase).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值