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
时,原始指针仍然存在。我也不能手动取消分配它们,我得到一个异常,说指针没有分配
所以我的问题是:
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;
}