C++ 如何将智能指针与setUserData(void*)一起使用?

C++ 如何将智能指针与setUserData(void*)一起使用?,c++,c++11,cocos2d-x,cocos2d-x-3.0,C++,C++11,Cocos2d X,Cocos2d X 3.0,是否可以对节点用户数据使用c++11智能指针?以前有人试过吗 node->setUserData(void* usrData); node->getUserData(); 已解决: 我找到了一种在节点中存储对象的方法,而不必手动删除主题(当节点被销毁时会自动删除),它可能不是最好的解决方案,但它是一种解决方案,它涉及从CoCoCos2D::Ref类继承并使用节点setUserObject(Ref*ptr) 我就是这样做到的: 1) -创建一个从cocos2d::Ref类继承的类/结

是否可以对节点用户数据使用c++11智能指针?以前有人试过吗

node->setUserData(void* usrData);
node->getUserData();
已解决:

我找到了一种在节点中存储对象的方法,而不必手动删除主题(当节点被销毁时会自动删除),它可能不是最好的解决方案,但它是一种解决方案,它涉及从CoCoCos2D::Ref类继承并使用节点setUserObject(Ref*ptr)

我就是这样做到的:

1) -创建一个从cocos2d::Ref类继承的类/结构

2) -使用自定义属性和方法填充它

3) -确保对象调用autorelease()

4) -创建一个对象实例,并将其指针放在任何节点UserObject中,如下所示:

auto box = new Box;
this->setUserObject(box);// am putting it in the Layer UserObject
现在,每当层/节点被销毁时,长方体对象将自动销毁(无需删除)


PS:为了调用节点(节点、层、场景)析构函数,您应该正确退出cocos2d-x应用程序,以便能够正确地析构函数节点的子节点(调用子析构函数)。。。如果在模拟器中,只需按后退按钮,或者使用调用Director::end()的关闭按钮。

这是一条注释,但太长了

我不认为它像@Joachim Pileborg在评论中那样毫无希望(尽管他的观点原则上是正确的)。您只需假设
setUserData
只是观察,即它不执行与内存相关的操作,尤其是不执行
delete

然后,您可以简单地使用“外部”智能指针

auto ptr=std::make_unique();
节点->设置用户数据(ptr.get());
现在,如果程序以正确的方式退出,至少您不必手动删除
ptr
。但是,正如Joachim所提到的,当然您必须确保
ptr
节点中使用的时间尽可能长


或者,您可以在
节点
类周围编写一个小包装器,该类包含一个
shared_ptr ptr
变量,并提供一个
setUserData(shared_ptr)
方法。如果调用此方法,它首先复制共享指针,并在内部调用
node->setUserData(ptr.get())
方法。然后,保证底层对象保持活动状态。

如果函数未声明为接受智能指针,则“否”不是真的。您可以使用智能指针,然后将实际指针传递给函数,但如果智能指针决定删除其包含的指针,则存储的指针将有成为散乱指针的风险,这确实违背了使用智能指针的初衷(并非有意的双关语)。因此,即使我使用shared_ptr::get()使用setUserData的方法。。。智能指针仍将被删除?但是,如果即使节点userdata保留它,它仍将删除其指针,那么共享智能指针的意义何在?如果使用例如
some\u share\u ptr.get()
获取原始指针,共享指针如何能够跟踪原始指针?它就是不能,所以当所有共享指针超出范围时,指针将被删除,留下一个散乱的指针。但是如果我使用setUserData(&some_share_ptr)它还会被删除吗?这并不比使用共享指针对象的原始指针好多少。使用指向共享指针对象的指针不会修改用于跟踪共享指针对象的共享指针对象引用计数器。但是,如果在ptr离开作用域时指针将被释放,那么将指针存储在用户数据中有什么意义呢?@Joseph:点(在第一个备选方案中)确保智能指针在使用时不会离开作用域。但是,如果出现异常情况,它仍然会正确地执行
删除
-ing任务。如果您怀疑是否可以保持指针的活动状态,请使用第二种选择:将所有内容封装在存储智能指针的类中(这样可以确保它是活动的)。这与您的解决方案方法非常相似,但可能更通用一些(一个CRTP类就足够了,而不必为每个类重新应用您的解决方案)。由于cocos2d是开源的,我发现另一个解决方案是重载setuserdata()(因为它是虚拟的),并让它接受@davidhigh建议的智能指针。
auto box = new Box;
this->setUserObject(box);// am putting it in the Layer UserObject
auto ptr = std::make_unique<some_object>();
node->setUserData(ptr.get());