将 unique_ptr 与需要指针指针的接口一起使用到抽象类
Posted
技术标签:
【中文标题】将 unique_ptr 与需要指针指针的接口一起使用到抽象类【英文标题】:Using unique_ptr with an interface requiring pointer-pointer, to an abstract class 【发布时间】:2021-09-27 16:29:45 【问题描述】:我正在使用 RocksDB,它需要一个指向打开指针的指针:
rocksdb::DB* dbnullptr;
const rocksdb::Status status = rocksdb::DB::Open(options, path, &db);
正如预期的那样,我想使用unique_ptr
。但是,不幸的是,如果我这样做:
std::unique_ptr<rocksdb::DB> db;
const rocksdb::Status status = rocksdb::DB::Open(options, fileFullPath, &(db.get()));
我明白了:
error: lvalue required as unary ‘&’ operand
如果我使用原始指针然后创建一个unique_ptr
:
std::unique_ptr<rocksdb::DB> _db; // Class member
rocksdb::DB* db;
const rocksdb::Status status = rocksdb::DB::Open(options, fileFullPath, &db));
_db = std::make_unique<rocksdb::DB>(db);
我明白了:
error: invalid new-expression of abstract class type ‘rocksdb::DB’
return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
我该如何使用unique_ptr
?
【问题讨论】:
不应该是_db.reset(db);
吗?
我认为reset()
只有当它当前持有一个有效值时,否则它是make_unique
&(db.get())
翻译得到unique_ptr
所代表的地址,然后取地址的地址。不是你想要的。您收到的错误消息是因为返回的地址位于临时变量中,您无法获取临时地址。它们的存在时间还不够长,无法发挥作用。
@user4581301 这个页面隐含地暗示我可以在我希望的时候删除指针:rocksdb.org/docs/getting-started.html
好。消除了一个潜在的问题来源。
【参考方案1】:
使用原始指针接受来自Open()
的值是正确的解决方案,因为这是函数所期望的。
但是,您之后创建unique_ptr
的方式不正确。
改用这个:
std::unique_ptr<rocksdb::DB> _db; // Class member
...
rocksdb::DB* db;
const rocksdb::Status status = rocksdb::DB::Open(options, fileFullPath, &db);
_db = std::unique_ptr<rocksdb::DB>(db);
Online Demo
或者:
std::unique_ptr<rocksdb::DB> _db; // Class member
...
rocksdb::DB* db;
const rocksdb::Status status = rocksdb::DB::Open(options, fileFullPath, &db);
_db.reset(db);
Online Demo
std::make_unique()
创建指定类型的新对象,然后将原始指针包装在新的std::unique_ptr
中。
另一方面,unique_ptr::operator=
和 unique_ptr::reset()
只是用新的原始指针更新现有的std::unique_ptr
(销毁被替换的旧原始指针指向的对象)。
由于rocksdb::DB
是一种抽象类型,您不能直接创建它的实例,这就是您的std::make_unique()
调用无法编译的原因。但是,即使您可以直接创建 DB
对象,std::make_unique<rocksdb::DB>(db)
也会将 db
作为参数传递给 rocksdb::DB
构造函数,这在这种情况下无论如何都不是您想要的。您只希望_db
智能指针拥有db
原始指针的所有权。
【讨论】:
以上是关于将 unique_ptr 与需要指针指针的接口一起使用到抽象类的主要内容,如果未能解决你的问题,请参考以下文章
如何将 unique_ptr 与 std::copy 一起使用?