【问题标题】:Using unique_ptr with an interface requiring pointer-pointer, to an abstract class将 unique_ptr 与需要指针指针的接口一起使用到抽象类
【发布时间】:2021-09-27 16:29:45
【问题描述】:

我正在使用 RocksDB,它需要一个指向打开指针的指针:

rocksdb::DB* db{nullptr};
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
  • &amp;(db.get()) 翻译得到unique_ptr 所代表的地址,然后取地址的地址。不是你想要的。您收到的错误消息是因为返回的地址位于临时变量中,您无法获取临时地址。它们的存在时间还不够长,无法发挥作用。
  • @user4581301 这个页面隐含地暗示我可以在我希望的时候删除指针:rocksdb.org/docs/getting-started.html
  • 好。消除了一个潜在的问题来源。

标签: c++


【解决方案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&lt;rocksdb::DB&gt;(db) 也会将 db 作为参数传递给 rocksdb::DB 构造函数,这在这种情况下无论如何都不是您想要的。您只希望_db 智能指针拥有db 原始指针的所有权。

【讨论】:

    猜你喜欢
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 2017-11-08
    • 2012-12-03
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多