我正在编写一个游戏框架,我有一个vector<unique_ptr<Object>>
列表,我通过调用object.get()
并将其发送出来,从该列表中分发指针。在此之前我发送引用而不是原始指针,但这导致了其他奇怪的问题所以我被告知这是更好的。但是,当我从列表中删除unique_ptr<Object>
时,原始指针仍然存在。我也无法手动释放它们,我得到一个例外,说没有分配指针。
所以我的问题是:
也是一个更普遍的问题:
PxlObject* PxlFramework::AddObject(PxlObject* obj)
{
std::unique_ptr<PxlObject> u_ptr(obj);
objects_iterator = objects.insert(objects.end(), std::move(u_ptr));
return obj;
}
void PxlFramework::DeleteObject(PxlObject* obj) {
for(objects_iterator = objects.begin(); objects_iterator != objects.end(); ++objects_iterator)
{
if((*objects_iterator)->get_id() == obj->get_id())
{
//attempting to delete the raw pointer here but it will result in an error
delete obj;
//removing the unique_ptr<PxlObject> from the list here
std::swap((*objects_iterator), objects.back());
objects.pop_back();
break;
}
}
}
答案 0 :(得分:2)
std::unique_ptr
的重点是它“拥有”该对象,并在unique_ptr
被销毁时自动管理删除。因此,您不应delete
unique_ptr
或unique_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 ...;
}
答案 1 :(得分:0)
您不需要直接删除原始指针,而是可以使用vector.erase。这里有一个简单的例子:
#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;
}
其他事情,我同意@MooingDuck:你不应该删除unique_ptr或者unique_ptr拥有的任何东西。但你确定可以。看看unique_ptr.release。此函数释放托管对象的所有权。