c – shared_ptr问题从成员函数返回上传版本
我最近一直在尝试使用shared_ptr,而且我遇到了一些奇怪的情况.我想要的是一个模板成员函数,它能够返回其派生类型的shared_ptr.我正在运行visual studio 2010,它可以访问一些新的c 0x标准,但我认为boost shared_ptr的行为类似.
这很好用的指针.我刚刚返回了一个dynamic_cast< DerivedClass *>(这个).但是,我有点难过,因为即使使用enable_shared_from_this,对象也会在调用函数后尝试删除自身(这很糟糕).我可能正在接近这个错误,但我想弄清楚如何模拟以下的裸指针等效(这是有效的)(这是我遇到的代码). //assume we have a virtual function as well. class BaseClass : public std::enable_shared_from_this<BaseClass> { .... template<typename DerivedClass> std::shared_ptr<DerivedClass> BaseClass::getThis(){ //I had some assert code here to ensure typeid matched return std::dynamic_pointer_cast<DerivedClass>(shared_from_this()); } } 编辑:似乎功能正常,问题在于我如何使用它.这很糟糕,例如执行以下操作: std::shared_ptr<DerivedClass> p = std::make_shared<DerivedClass>(); p->getType<DerivedClass>->someOtherFunctionOnlyInTheDerivedClass(); 这不是问题: std::shared_ptr<BaseClass> p = std::make_shared<DerivedClass>(); p->getType<DerivedClass>->someOtherFunctionOnlyInTheDerivedClass(); 我不完全确定转换为相同类型或引用计数问题是否存在问题.在任何情况下,我都做了一些愚蠢的事情并且它已经破坏了,避免了那时不必要的getType调用似乎在我使用它的其他每种情况下都能正常工作.也许有人可以准确地解释是什么原因导致第一个例子与第二个例子一起工作.我会为那个答案分配点数. 解决方法
为了扩展Stuart的答案并(可能)解释你崩溃的原因,我最好的猜测是你在stack-alloc’d实例上调用了getType.这是使用enable_shared_from_this的一个主要缺陷.
#include <memory> class Base : public std::enable_shared_from_this<Base> { public: virtual ~Base() {} template <typename D> std::shared_ptr<D> getType() { return std::dynamic_pointer_cast<D>(shared_from_this()); } }; class Derived : public Base { public: void f() {} }; int main() { std::shared_ptr<Derived> d = std::make_shared<Derived>(); d->getType<Derived>()->f(); // fine Derived d2; Base* p = &d2; p->getType<Derived()>->f(); // will attempt to delete d2 after f() returns. return 0; } 发生这种情况的原因是因为当它在堆栈上时d2的引用计数为零.调用shared_from_this会返回一个shared_ptr,它将引用计数增加到1.一旦该指针超出范围,它将其计数减少到零,然后尝试删除实例,当然,该实例位于堆栈上. 我能想到保护自己免受这种影响的唯一方法就是让所有构造函数都受到保护或私有,并提供动态分配任何实例的静态函数,当然还要返回shared_ptrs. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- dart – Flutter – 在BottomNavigationBar中显示PopupMenu
- kali2.0配置msf连接postgresql数据库
- 在C#中将字节数组转换为包含字节数组的类
- 操纵SQLite
- vb.net – VisualStudio 2008中的Autocomment”’停止工作
- 909422229__XML语言的学习
- 具有OnComplete的Ajax.BeginForm始终更新页面
- .net – ServiceStack遇到异常:底层连接已关闭:超出了消息
- 未能加载文件或程序集“XXX”或它的某一个依赖项。系统找不
- c# – 当值在数组中时选择的MVC5 Razor html.dropdownlist