sharedfromthis几个值得注意的地方.docx
- 文档编号:10527476
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:5
- 大小:16.06KB
sharedfromthis几个值得注意的地方.docx
《sharedfromthis几个值得注意的地方.docx》由会员分享,可在线阅读,更多相关《sharedfromthis几个值得注意的地方.docx(5页珍藏版)》请在冰豆网上搜索。
sharedfromthis几个值得注意的地方
shared_from_this几个值得注意的地方
shared_from_this()是enable_shared_from_this<T>的成员函数,返回shared_ptr<T>。
首先需要注意的是,这个函数仅在shared_ptr<T>的构造函数被调用之后才能使用。
原因是enable_shared_from_this:
:
weak_ptr并不在构造函数中设置,而是在shared_ptr<T>的构造函数中设置。
如下代码是错误的:
classD:
publicboost:
:
enable_shared_from_this<D>
{
public:
D()
{
boost:
:
shared_ptr<D>p=shared_from_this();
}
};原因很简单,在D的构造函数中虽然可以保证enable_shared_from_this<D>的构造函数已经被调用,但正如前面所说,weak_ptr还没有设置。
如下代码也是错误的:
classD:
publicboost:
:
enable_shared_from_this<D>
{
public:
voidfunc()
{
boost:
:
shared_ptr<D>p=shared_from_this();
}
};voidmain()
{
Dd;
d.func();
}错误原因同上。
如下代码是正确的:
voidmain()
{
boost:
:
shared_ptr<D>d(newD);
d->func();
}这里boost:
:
shared_ptr<D>d(newD)实际上执行了3个动作:
首先调用enable_shared_from_this<D>的构造函数;其次调用D的构造函数;最后调用shared_ptr<D>的构造函数。
是第3个动作设置了enable_shared_from_this<D>的weak_ptr,而不是第1个动作。
这个地方是很违背c++常理和逻辑的,必须小心。
结论是,不要在构造函数中使用shared_from_this;其次,如果要使用shared_ptr,则应该在所有地方均使用,不能使用Dd这种方式,也决不要传递裸指针。
另一个值得注意的地方是在类的继承树中不能有2个或更多个enable_shared_from_this<T>。
例如如下代码是错误的:
classA:
publicboost:
:
enable_shared_from_this<A>
{
public:
A():
a
(1){}
virtual~A(){}
boost:
:
shared_ptr<A>get_ptra(){returnshared_from_this();}
inta;
};classB:
publicA,publicboost:
:
enable_shared_from_this<B>
{
public:
B():
b
(2){}
boost:
:
shared_ptr<B>get_ptrb()
{
returnboost:
:
enable_shared_from_this<B>:
:
shared_from_this();
}
intb;
};int_tmain(intargc,_TCHAR*argv[])
{
{
boost:
:
shared_ptr<B>x(newB);
boost:
:
shared_ptr<A>a1=x->get_ptra();
boost:
:
shared_ptr<B>b1=x->get_ptrb();
}return0;
}注意上面代码中,B同时拥有2个enable_shared_from_this的基类,一个是enable_shared_from_this<A>,另一个是enable_shared_from_this<B>。
在boost:
:
shared_ptr<B>x(newB);这行代码中,shared_ptr<B>的构造函数仅会设置2个基类中的一个的weak_ptr。
在上面的例子中,仅设置enable_shared_from_this<A>的。
如果修改B的定义为:
classB:
publicboost:
:
enable_shared_from_this<B>,publicA,则仅设置enable_shared_from_this<B>的weak_ptr。
很明显都是错误的。
那么enable_shared_from_this以及shared_ptr为何要如此实现呢?
又为什么会有如此怪异的结果呢?
首先考察shared_ptr的构造函数:
template<classY>
explicitshared_ptr(Y*p):
px(p),pn(p)//Ymustbecomplete
{
boost:
:
detail:
:
sp_enable_shared_from_this(pn,p,p);
}template<classT,classY>voidsp_enable_shared_from_this(shared_countconst&pn,boost:
:
enable_shared_from_this<T>const*pe,Yconst*px)
{
if(pe!
=0)pe->_internal_weak_this._internal_assign(const_cast<Y*>(px),pn);
}注意这个sp_enable_shared_from_this是一个模板函数,而且仅调用了一次,所以不可能2个enable_shared_from_this基类的weak_ptr都被赋值。
但问题在于,在调换了B的定义之后结果居然是不一样的。
这里有一个很隐秘的编译器BUG。
按道理来说,编译器在编译这段代码时,应该注意到无法真正决断该怎么实例化sp_enable_shared_from_this并且报一个错,但vc2008并没有报错,而是通过编译了。
(g++会在此处报错)那么正确的解法是怎样的呢?
classB:
publicA
{
public:
B():
b
(2){}
boost:
:
shared_ptr<B>get_ptrb()
{
returnboost:
:
dynamic_pointer_cast<B>(shared_from_this());
}
intb;
};
注意到这里B并没有直接继承enable_shared_from_this,而是使用dynamic_pointer_cast进行了类型转换。
关于为什么enable_shared_from_this是这样实现的,可以参看作者原文:
Everyenable_shared_from_thisbasecontainsaweak_ptr,Theshared_ptrconstructorlooksuptheenable_shared_from_thisbaseandinitializesitsweak_ptraccordingly.Thisdoesn'tworkwhenthereare
twoormoreenable_shared_from_thisbases,though.Icouldputtheweak_ptrinavirtualpolymorphicbase.Thiswouldforcepolymorphismonallclientsofenable_shared_from_this...probablyacceptable.Itwillalsoforceadynamic_pointer_castinevery
shared_from_this,andthismaybehardertoswallow,particularlyincaseswhereRTTIisoff.SoI'mnotsure.Ifyoudowanttheabovebehavior,it'seasytoduplicate,asIalreadyrespondedinmyfirstpostonthetopic.JustmakeFooBreturndynamic_pointer_cast<B>(FooA())andremovetheenable_shared_from_this<B>
base(Aneedstobemadepolymorphic,ofcourse).注意为了让dynamic_pointer_cast能工作,A必须具有虚函数,那么最简单的做法当然是令其析构函数为虚函数(通常一个class如果希望被继承,析构函数就应该为虚函数)。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- sharedfromthis 几个 值得 注意 地方
![提示](https://static.bdocx.com/images/bang_tan.gif)