【问题标题】:Transferring ownership to a manager将所有权转让给经理
【发布时间】:2014-07-21 08:33:19
【问题描述】:

我正在尝试为基于组件的系统中的实体编写管理类。我不确定如何继续将实体添加到此类中。我有几种方法可以做到这一点,但是我不确定正确的方法是什么。

第一种方法是将对象移动到管理器中。

void addEntity(Entity && in){
  entities.emplace(std::move(in));
}

但是,我需要处理移动构造函数,这应该不会太难。

另一种方法是传入一个指针或std::unique_ptr。这样一来,我就不必担心所有权,因为它会使传入的指针无效。

void addEntity(std::unique_ptr<Entity> in){
  entities.emplace(in);
}

但是,我不确定哪种方法更好。

【问题讨论】:

  • “将对象移入管理器”的真正含义是什么?为什么不简单地将对象的地址提供给经理并将其留在原处?
  • 在没有更多上下文的情况下很难确定,但第一个对我来说似乎很好。考虑第二个的主要原因之一是如果您正在处理多态 Entity 类型。
  • @wallyk 我希望经理拥有实体的所有权。我可能会从文件中读取这些实体,并将它们按顺序添加到管理器中,以便它们在需要时被销毁,否则会存在于其中。
  • @Praetorian Enttiy 不会是多态类型。

标签: c++ memory c++11 memory-management ownership


【解决方案1】:

第一种方法仅在您使用客户端代码中的右值调用它时才有效。这是一个很大的限制,因此您必须为左值引用提供另一个重载。如果您使用完美转发到emplace 的“通用参考”,您实际上可以同时执行这两项操作。缺点是它使用模板,所以Entity 类型从签名中消失了:

template <typename T>
void addEntity(T&& in){
  entities.emplace(std::forward<T>(in));
}

unique_ptr 方式对客户端来说有点冗长,因为他们必须自己创建 unique_ptr

Entity entity(...);
manager.addEntity(std::make_unique<Entity>(entity)); // copy ctor
// or
manager.addEntity(std::make_unique<Entity>(std::move(entity))); // move ctor to heap

这取决于创建唯一对象应该由谁负责的决定。您是否希望 Manager 类拥有客户端为您准备的一些已经存在的唯一对象的所有权,或者您希望拥有一个更灵活的 Manager 类来根据提供的参数自行移动/复制。

我会选择完美的转发或两次重载解决方案,因为它会产生更清晰的界面和更好的客户端代码。

【讨论】:

    猜你喜欢
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 2014-08-29
    相关资源
    最近更新 更多