【问题标题】:Is it correct to return a raw pointer from a unique_ptr?从 unique_ptr 返回原始指针是否正确?
【发布时间】:2014-10-25 04:16:57
【问题描述】:

问题:如果原始指针仅用作引用,则从 unique_ptr 返回原始指针是否正确?

背景:为了一项挑战,我开始在空闲时间创建一个简单的 2D 游戏引擎。我有一个 Screen 基类和一个 ScreenManager 基类,每个基类都派生自。

屏幕将用于启动画面、选项菜单,当然还有非常重要的游戏屏幕。

ScreenManager 基类将用于(矢量化、堆叠等)管理器,可针对游戏需求进行指定。

详细信息:目前我的 Screen 类拥有一个指向管理它的 ScreenManager 的原始指针。就是这样,在当前屏幕中,它可以根据自己的状态选择下一个新的屏幕要推送到管理器上。

精简的 Sudo 代码示例 屏幕类

class ScreenManager; //Forward Declaration
class Screen {
protected: ScreenManager* m_manager; // Ptr reference to manager
public:
    explicit Screen(ScreenManager *manager) : m_manager(manager){}

    virtual void handleEvents(const event);
    // Possibly call m_manager->changeScreen(newScreenUPtr)
    virtual void update(const time, const window);
    virtual void render(const time, window);
}

ScreenManager 类

class ScreenManager {
// Implementation specific container of Screens
private:
    virtual void handleEvents(const event); // Call active screens handleEvents()
    virtual void update(const time, const window); // Same, for update()
    virtual void render(const time, window); // Same, for render()
public:
    virtual void changeScreen(unique_ptr<Screen> newScreen); 
}

重新查询:有没有比将 ScreenManager 指针放入 Screen 类更好的方法,还是我做对了?

【问题讨论】:

  • 谁拥有谁?将“拥有 Y 类型的 X”表示为 unique_ptr&lt;Y&gt; X。将“对 Y 类型的 X 的非拥有引用”表示为纯 Y* x。如果你有两件东西自以为是,那你的日子会很糟糕。
  • 如果它是非拥有的,原始指针就可以了。 (或者你可以写一些类似提议的observer_ptr,世界上最笨的智能指针(TM),以明确非拥有性。)
  • virtual void changeScreen(unique_ptr&lt;Screen&gt; newScreen); 我很确定这不会编译;它需要复制unique_ptr&lt;Screen&gt;,但不能复制unique_ptr。如果您希望 changeScreen 声明所有权,请使用 unique_ptr&lt;Screen&gt;&amp;&amp; newScreen 并离开它。
  • @IgorTandetnik:只要你传递一个 r 值,只按值进行移动不是问题。只有当您尝试将左值传递给它时才会出现错误。

标签: c++ pointers c++11 unique-ptr


【解决方案1】:

这是一个后向指针模式,对吧? A 指向拥有所有权的 B,而 B 指向没有所有权的 A。

完全可靠的方法是使用 shared_ptr 和 weak_ptr。如果这是单线程的,您可以在父指针声明中记录规则,并注意 unique_ptr 导致 B 在 A 被销毁时首先被销毁。所以这是安全的,如果您不会滥用指针或稍后更改代码并改变情况。因此,cmets 和好名字很重要。同意,编译器不能强制执行所有可能的误用,也不能擦鼻子。

在现实世界的代码中,您可以指望有人稍后添加功能并扰乱任何“OK,因为它都是正确的”。

【讨论】:

  • 真正的代码已经记录在案了,也许太彻底了。我喜欢共享/弱 ptr 概念。我对编程概念和术语比较陌生。我将查找“反向指针”并在我的开发分支上进行一些测试。
【解决方案2】:

是的,只要 ScreenManager 比包含的 Screens 寿命长,那么我认为你做对了。

您可能希望通过引入更稳定的接口来打破ScreenScreenManager 之间的循环依赖关系,例如IScreenManager,但这很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    相关资源
    最近更新 更多