指针变为 unique_ptr 后会发生什么?

What happens to a pointer after it has become a unique_ptr?

我有一个函数可以创建一个指向动态分配对象“c”的唯一指针。

template<typename T, typename... TArgs> void addComponent(TArgs&&... MArgs) {

    if(!components.count(typeid(T))) {
        T* c = new T(std::forward<TArgs>(MArgs)...);
        c->entity = this;
        std::unique_ptr<Component> uPtr{ c };
        components[typeid(T)] = (std::move(uPtr));
        c->init();
    }

}

我的理解是 unique_ptr 控制了 c 的值,因为你不能让另一个指针也指向 a unique_ptr,但是 c->init 在 c 之后仍然有效变成了unique_ptr.

为什么这行得通? c 是否仍以某种方式指向相同的 new T() 还是创建了一个全新的对象?

没有创建新对象,也没有任何东西可以控制任何东西。你用智能指针包裹了原始指针,不应该再使用原始指针了。

智能指针只有在您不使用原始指针解决它们的情况下才能工作。但是变量 c 的值不会因为 std::unique_ptr 构造函数中的赋值运算符而改变。它保持不变,作为程序员的你应该受到约束,不要再直接使用它。

好的做法是将它作为一个临时变量,在它被包装到一个智能指针后消失;或者不用 new 只使用 std::make_unique.

unique_ptr 对象存储了 c 值的副本。当 unique_ptr 对象被销毁时,其析构函数将调用 delete 存储的指针值。

原变量c没有被unique_ptr修改,继续指向同一个对象。取消引用它是完全没问题的。重要的是,由于此指针值将被 unique_ptr 自动删除,(1)您不得在 unique_ptr 的生命周期到期后继续使用其值,以及(2)您不得尝试手动删除它。

将原始指针包裹在智能指针内不会改变原始指针的任何内容。它仍然指向它最初指向的同一内存。智能指针只是复制指针,然后为您管理 pointed-at 内存,当智能指针被销毁或以其他方式分配给不同的指针时,delete'ing 内存。

仅供参考,使用std::make_unique()而不是new会更安全、更高效,例如:

template<typename T, typename... TArgs>
void addComponent(TArgs&&... MArgs) {
    if (!components.count(typeid(T))) {
        auto c = std::make_unique<T>(std::forward<TArgs>(MArgs)...);
        c->entity = this;
        c->init();
        components[typeid(T)] = std::move(c);
    }
}