我想知道如何在结构中声明一个唯一的ptr并在以后初始化它。现在我有
struct CacheObject {
std::string _cache_type;
std::unique_ptr<faiss::Cache> cache;
uint64_t _cache_size;
// Real time data
int64_t rt_byte_req;
int64_t rt_byte_miss;
int64_t rt_obj_req;
int64_t rt_obj_miss;
CacheObject();
};
和
CacheObject::CacheObject() : _cache_type("LRU"), cache(nullptr),
_cache_size(5000), rt_byte_req(0), rt_byte_miss(0),
rt_obj_req(0), rt_obj_miss(0) {}
但我收到一条错误消息说
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = faiss::Cache; _Dp = std::default_delete<faiss::Cache>]’
arg2 = *temp;
为什么会发生这种情况,我该如何修改?谢谢
std::unique_ptr
不能被复制,只能被移动,因此编译器不能为结构生成复制赋值operator=
。因此,像arg2 = *temp;
这样的语句,其中arg2
和*temp
是CacheObject
对象,默认情况下将不起作用。
您需要实现自己的拷贝分配operator=
来克隆faiss::Cache
对象,例如:
struct CacheObject {
...
std::unique_ptr<faiss::Cache> cache;
...
CacheObject& operator=(const CacheObject &rhs)
{
if (this != &rhs)
{
if (rhs.cache)
cache.reset(new faiss::Cache(*(rhs.cache))); // or equivalent...
else
cache.reset();
// copy other members as needed...
}
return *this;
}
};
...
arg2 = *temp;
和/或,实现移动分配operator=
,将unique_ptr
从一个CacheObject
移动到另一个,例如:
struct CacheObject {
...
std::unique_ptr<faiss::Cache> cache;
...
CacheObject& operator=(CacheObject &&rhs)
{
cache = std::move(rhs.cache);
// move other members as needed...
return *this;
}
};
...
arg2 = std::move(*temp);
这是对@remylebeau已经提到的内容的修正。std::unique_ptr<>
也具有reset()
成员功能。你也可以这样
struct CacheObject {
// ....
void SetCacheObject(faiss::Cache* p)
{
if (p) {
// This assumes you're resetting it because you no longer
// care about what it pointed to
delete cache.release();
}
cache.reset(p);
}
};
void SomeFunc()
{
CacheObject co;
// ... elsewhere and after important stuff
co.SetCacheObject(new faiss::Cache());
}
您可以参考此链接进行重置,也可以参考此链路进行释放。
编辑
经过思考,我认为重要的是要提到,如果您应该使用这种方法并且std::unique_ptr<faiss::Cache>
对象有一个有效的引用,除非您正确处理它,否则您将泄漏内存。我已经用更改了代码示例,这是防止这种情况的一种可能方法。