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

How to use smart pointers with setUserData(void*)?

本文关键字:void 一起 setUserData 智能 指针      更新时间:2023-10-16

是否可以将 C++11 智能指针与节点用户数据一起使用? 以前有人尝试过吗?

node->setUserData(void* usrData);
node->getUserData();

解决:

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

这就是我实现它的方式:

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

2)- 用您的自定义属性和方法填充它。

3)- 确保对象调用自动发布()。

struct Box : public cocos2d::Ref
{
    // some properties here
    Box() {
        //autorelease means let other Nodes retain and release this object.
        //if you don't call autorelease then the object destructor won't get called which means in turn object memory is not released.
        this->autorelease();
    }
    ~Box() {
        //just to check if the object destructor is called or not.
        log("=========================");
        log("Box is destroyed"); 
        log("=========================");
    }
};

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

auto box = new Box;
this->setUserObject(box);// am putting it in the Layer UserObject

现在,每当层/节点被销毁时,Box 对象将被自动销毁(无需删除)

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

这是一个评论,但太长了。

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

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

auto ptr = std::make_unique<some_object>();
node->setUserData(ptr.get());

现在,如果程序以正确的方式退出,至少您不必手动删除ptr。但是,正如约阿希姆所提到的,当然你必须确保ptr存在的时间,只要它可能在node中使用。

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