C++ 如何从唯一的\u ptr中删除原始指针

C++ 如何从唯一的\u ptr中删除原始指针,c++,pointers,unique-ptr,delete-operator,C++,Pointers,Unique Ptr,Delete Operator,我正在编写一个游戏框架,我有一个向量列表,我通过调用object.get()并发送它来分发该列表中的指针。在此之前,我发送引用而不是原始指针,但这导致了其他奇怪的问题,所以我被告知这更好。但是,当我从列表中删除一个唯一的\u ptr时,原始指针仍然存在。我也不能手动取消分配它们,我得到一个异常,说指针没有分配 所以我的问题是: 如何从已删除的唯一\u ptr中删除原始指针 这也是一个更一般的问题: 我是否在传递指针而不是引用的正确轨道上 pxlbject*PxlFramework::AddObj

我正在编写一个游戏框架,我有一个
向量
列表,我通过调用
object.get()
并发送它来分发该列表中的指针。在此之前,我发送引用而不是原始指针,但这导致了其他奇怪的问题,所以我被告知这更好。但是,当我从列表中删除一个
唯一的\u ptr
时,原始指针仍然存在。我也不能手动取消分配它们,我得到一个异常,说指针没有分配

所以我的问题是:

  • 如何从已删除的唯一\u ptr中删除原始指针 这也是一个更一般的问题:

  • 我是否在传递指针而不是引用的正确轨道上
  • pxlbject*PxlFramework::AddObject(pxlbject*obj)
    {
    std::唯一的ptr(obj);
    objects_iterator=objects.insert(objects.end(),std::move(u_ptr));
    返回obj;
    }
    void PxlFramework::DeleteObject(pxlbject*obj){
    对于(objects_iterator=objects.begin();objects_iterator!=objects.end();++objects_iterator)
    {
    if((*objects\u iterator)->get\u id()==obj->get\u id())
    {
    //试图在此处删除原始指针,但会导致错误
    删除obj;
    //从此处的列表中删除唯一的\u ptr
    std::swap(*objects\u迭代器),objects.back();
    objects.pop_back();
    打破
    }
    }
    }
    
    std::unique\u ptr
    的要点在于它“拥有”对象,并在销毁
    unique\u ptr
    时自动管理删除。因此,您不应
    删除
    唯一\u ptr
    唯一\u ptr
    拥有的任何内容。为了避免这种混淆,引用更为常见。此外,您的
    AddObject
    返回一个指向一个
    PxlObject
    的指针,而该对象不是刚刚添加的对象

    像这样的东西可能会更干净一些:

    template<class Us...>
    PxlObject& PxlFramework::AddObject(Us&&... obj)
    {
        std::unique_ptr<PxlObject> u_ptr(new PxlObject(std::forward<Us>(obj)...));
        objects_iterator = objects.insert(objects.end(), std::move(u_ptr));
        return **objects_iterator;
    }
    
    void PxlFramework::DeleteObject(PxlObject& obj) {
        auto finder = [](std::unique_ptr<PxlObject>& p)->bool 
                {return obj.get_id()==p->get_id();};
        auto it = find_if(objects.begin(), objects,end(), finder);
        if (it != objects.end())
            objects.erase(it);
        else
            throw ...;
    }
    
    模板
    pxlbject&PxlFramework::AddObject(Us&…obj)
    {
    std::unique_ptr u_ptr(新PxlObject(std::forward(obj)…);
    objects_iterator=objects.insert(objects.end(),std::move(u_ptr));
    返回**对象\迭代器;
    }
    void PxlFramework::DeleteObject(pxlbject&obj){
    自动查找器=[](标准::唯一\u ptr&p)->bool
    {return obj.get_id()==p->get_id();};
    auto it=find_if(objects.begin(),objects,end(),finder);
    if(it!=objects.end())
    对象。擦除(它);
    其他的
    扔。。。;
    }
    
    您不需要直接删除原始指针,而是可以使用它。这里有一个简单的例子:

    #include <iostream>
    #include <algorithm>
    #include <memory>
    #include <vector>
    
    using namespace std;
    
    typedef vector<unique_ptr<int>> ptr_list_t;
    
    void remove_number(int x, ptr_list_t& ptr_list)
    {
        for (ptr_list_t::iterator it = ptr_list.begin(); it != ptr_list.end(); ++it)
            if (*(it->get()) == x) {
                ptr_list.erase(it);     // Use vector.erase for deleting objects from a vector.
                                        // since it points to a unique_ptr, the object owned by it
                                        // will be destroyed automatically.
                break;
            }
    }
    
    int main()
    {
        ptr_list_t ptr_list;
    
        // Generating the pointer to numbers. 0 - 9
        for (int i = 0; i < 10; i++)
            ptr_list.push_back(unique_ptr<int>(new int(i)));
    
        // Remove the number 3.
        remove_number(3, ptr_list);
    
        // Printing the list. The number 3 will not appear.
        for (ptr_list_t::iterator it = ptr_list.begin(); it != ptr_list.end(); ++it)
            cout << *(it->get()) << endl;
    
        return 0;
    }
    
    #包括
    
    #包括。此函数释放托管对象的所有权。

    您不会删除属于智能指针的指针,它们是自己删除的,这是它们的全部目标,也是它们生命中唯一的目标,亲自删除会伤到它们的心和您的代码。如果您需要共享所有权,则应使用shared\u ptr。unique_ptr是对象的唯一所有者,因此在对象的生命周期结束后,您不应该有其内容的副本。一个问题是您的
    AddObject
    函数。它将随机指针传递给一个
    唯一的\u ptr
    。这是一个错误。只有使用
    new
    创建的指针才应传递到
    unique\u ptr
    ,因为
    unique\u ptr
    将对其调用
    delete
    。修复方法是使
    AddObject
    具有
    唯一性&&
    。另一个修复方法是使用
    PxlObject&&
    。但我遇到的问题是,即使在我使用引用调用DeleteObject之后,该引用仍将存在并携带相同的数据。@user3680720:引用存在,但数据已消失。它指的是数据过去在哪里。简单地说,不要在这一点之后使用这些引用。如果这不可能,那么代码中的其他位置也需要共享PxlObject的所有权,在这种情况下,您可能需要不同的设计,使用
    std::shared_ptr
    。好的,因此AddObject方法将返回一个引用,但引用不能为null,那么,如果找不到对象或者只是抛出错误,那么我应该在FindObject方法中返回什么呢?如果找不到元素,大多数容器都会向
    end()
    返回迭代器。
    #include <iostream>
    #include <algorithm>
    #include <memory>
    #include <vector>
    
    using namespace std;
    
    typedef vector<unique_ptr<int>> ptr_list_t;
    
    void remove_number(int x, ptr_list_t& ptr_list)
    {
        for (ptr_list_t::iterator it = ptr_list.begin(); it != ptr_list.end(); ++it)
            if (*(it->get()) == x) {
                ptr_list.erase(it);     // Use vector.erase for deleting objects from a vector.
                                        // since it points to a unique_ptr, the object owned by it
                                        // will be destroyed automatically.
                break;
            }
    }
    
    int main()
    {
        ptr_list_t ptr_list;
    
        // Generating the pointer to numbers. 0 - 9
        for (int i = 0; i < 10; i++)
            ptr_list.push_back(unique_ptr<int>(new int(i)));
    
        // Remove the number 3.
        remove_number(3, ptr_list);
    
        // Printing the list. The number 3 will not appear.
        for (ptr_list_t::iterator it = ptr_list.begin(); it != ptr_list.end(); ++it)
            cout << *(it->get()) << endl;
    
        return 0;
    }