游戏ECS开发中std::unique_ptr初始化语法的技术疑问
std::unique_ptr<Entity> uPtr{ e }; in Your ECS addEntity Function Let’s break down what that line does, why it works in your code, and how you can make it even safer:
First, let’s recap the full function context:
Entity& addEntity() { Entity* e = new Entity(); std::unique_ptr<Entity> uPtr{ e }; entities.emplace_back(std::move(uPtr)); return *e; }
What std::unique_ptr<Entity> uPtr{ e }; does
eis a raw pointer pointing to a newly allocatedEntityon the heap (fromnew Entity()).- This line constructs a
std::unique_ptrthat takes exclusive ownership of the raw pointere. From this point on, theunique_ptris responsible for deleting theEntitywhen it’s no longer needed—you don’t have to calldeletemanually.
Why this works in your code
When you call entities.emplace_back(std::move(uPtr)), you’re transferring ownership of the Entity from the local uPtr to the std::unique_ptr<Entity> stored in your entities vector. Since unique_ptr doesn’t allow copying (it’s "unique"), you use std::move to hand off ownership instead of creating a copy. Returning *e is safe because the vector now owns the Entity and will keep it alive as long as the vector holds the element.
A more robust alternative
While your code behaves as expected, directly pairing new with unique_ptr carries a small risk: if an exception were thrown between new Entity() and assigning to uPtr, the raw pointer e would leak memory. Instead, use std::make_unique<Entity>()—a modern C++ utility that allocates the object and returns a unique_ptr in one atomic step, eliminating that risk:
Entity& addEntity() { auto uPtr = std::make_unique<Entity>(); Entity* e = uPtr.get(); // Get a non-owning raw pointer to return a reference entities.emplace_back(std::move(uPtr)); return *e; }
This does exactly the same job as your original code but follows best practices for safe memory management. The get() method gives you access to the underlying raw pointer without transferring ownership, which is safe here because we’ve already moved the unique_ptr into the vector before returning the reference.
Quick unique_ptr reminders
- It enforces exclusive ownership of a heap object—only one
unique_ptrcan own the object at a time. - You can’t copy a
unique_ptr, only move it (which transfers ownership to anotherunique_ptr). - It automatically deletes the object it owns when it goes out of scope (unless ownership was moved elsewhere).
内容的提问来源于stack exchange,提问作者Marko Beocanin

