使用make_unique创建唯一指针并移动



我有一个带有私有构造函数和公共CreateEntity函数的Entity类。CreateEntity堆栈分配新实体。在我的应用程序中,我想使用一个指向返回实体的唯一指针。我找到了一个具有临时唯一指针和两条移动指令的解决方案。如何使用make_unique和单个move指令来编写Start((中的两行?

class Entity
{
public:
Entity(const Entity&) = delete;
Entity& operator=(const Entity&) = delete;
Entity(Entity&&) = default;
Entity& operator=(Entity&&) = default;
static Entity CreateEntity();
private:
Entity(id_t id): m_ID(id) {}
private:
uint32_t m_ID;
};
Entity Entity::CreateEntity()
{
static id_t currentID = 0;
return Entity{currentID++};
}
struct Lucre : public Application
{
bool Start();
std::unique_ptr<Entity> m_Object;
}
bool Lucre::Start()
{
std::unique_ptr<Entity> ptr( new Entity(std::move(Entity::CreateEntity())));
m_Object = std::move(ptr);
}

您可以像这样组合Lucre::Start()中的两行:

m_CameraObject.reset( new Entity( Entity::CreateEntity() ) );

这里,Entity::CreateEntity()的返回被移动,但不需要std::move(),因为返回已经是prvalue。

只是复制所示行的行为:

m_CameraObject = std::make_unique<Entity>(Entity::CreateEntity());

这将执行Entity的单移动构造和std::unique_ptr的单移动指派(假设m_CameraObject是类型std::unqiue_ptr<Entity>(,此外还执行Entitystd::unqiue_ptr的非移动/复制对象构造(在C++17或更高版本中保证,否则可能(。

由于Entity::CreateEntity()std::make_unique<Entity>(Entity::CreateEntity())都已经是prvalue,因此在此不需要std::move。在您的原件中,Entity::CreateEntity()周围的std::move也是多余的。

然而,如果没有完整的代码,很难判断这是否是你真正想要做的。也许让工厂函数直接返回std::unique_ptr<Entity>是更好的选择。那么就不需要为Entity调用move构造函数了。

我可能没有正确理解您的需求,但下面的示例代码:

  • 还实现了Entity对象,使每个实例都有不同的ID
  • 仍然隐藏Entity类的实现细节。之前,您使用auto e = Entity::CreateInstance();创建了一个Entity对象。现在,您可以对auto e = Entity{};执行同样的操作。也就是说,在这两种情况下,用户对ID一无所知
  • 通过向Entity添加默认构造函数,简化了Entity堆实例的创建。现在,您可以使用m_Object{ std::make_unique<Entity>() }初始化您的Lucre::m_Object成员

【演示】

#include <cstdint>  // uint32_t
#include <iostream>  // cout
#include <memory>  // make_unique, unique_ptr
class Entity
{
public:
Entity(): m_ID{currentID++} {}
Entity(const Entity&) = delete;
Entity& operator=(const Entity&) = delete;
Entity(Entity&&) = default;
Entity& operator=(Entity&&) = default;
auto getID() const { return m_ID; }
friend std::ostream& operator<<(std::ostream& os, const Entity& e) { return os << e.m_ID; }
private:
static inline uint32_t currentID;
uint32_t m_ID;
};
struct Lucre
{
Lucre() : m_Object{ std::make_unique<Entity>() } {}
friend std::ostream& operator<<(std::ostream& os, const Lucre& l) { return os << l.m_Object->getID(); }
private:
std::unique_ptr<Entity> m_Object{};
};
int main()
{
Lucre lucre1{};
Lucre lucre2{};
std::cout << "lucre1 = " << lucre1 << ", lucre2 = " << lucre2 << "n";
}
// Outputs:
//
//   lucre1 = 0, lucre2 = 1

相关内容

  • 没有找到相关文章

最新更新