我正在尝试为基于组件的系统中的实体编写管理类。我不确定如何继续在这个类中添加实体。我有几种方法可以做到这一点,但我不确定正确的方法是什么。
第一种方法是将对象移动到管理器中。
void addEntity(Entity && in){
entities.emplace(std::move(in));
}
然而,我需要处理移动构造函数,这不应该太难。
另一种方法是传入指针或std::unique_ptr
。这样,我不需要担心所有权,因为它会使传入的指针无效。
void addEntity(std::unique_ptr<Entity> in){
entities.emplace(in);
}
但是,我不确定哪种方法更好。
答案 0 :(得分:3)
第一种方法只有在使用客户端代码中的rvalues调用它时才有效。这是一个很大的限制,因此您必须为左值引用提供另一个重载。如果你使用&#34;通用引用&#34;实际上你可以同时做两件事。完美转发到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类,该类将根据提供的参数进行移动/复制。
我选择完美的转发或双重载解决方案,因为它可以提供更清晰的界面和更好的客户端代码。