-
如果T类型的一个对象obj的生命周期为:如果这个obj没有被其它对象(假设B)引用了,则析构。所以这个对象obj使用shared_ptr管理。但是一个问题是:B对象是obj中方法返回出来的,所以,在创建对象B的时候,就需要传obj的引用给他。为此引入enable_shared_from_this方便这个。
-
如果T继承了enable_shared_from_this,那么该类拥有了
shared_from_this()
方法,如果obj是使用名为pt的shared_ptr管理的,调用shared_from_this()
会返回和pt共享同一个obj的shared_ptr对象,如果obj没有没shared_ptr管理,调用该方法会出错。 -
使用场景: 创建要给数据对象,该数据对象可以返回迭代器用于迭代它,所以数据对象只有当其上面的所有迭代器对象都销毁时,其才可以销毁。为此选择数据对象类型继承enable_shared_from_this,这样其在创建迭代器时可以通过
shared_from_this()
方法返回当前this的引用。如果数据对象最开始不是一个shared_ptr,则将会出错。 -
参考:https://github.com/vesoft-inc/nebula/blob/master/src/kvstore/wal/FileBasedWal.cpp
class FileBasedWal final : public Wal
, public enable_shared_from_this<FileBasedWal> {
~FileBasedWal() {
// FileBasedWal inherits from std::enable_shared_from_this, so at this
// moment, there should have no other thread holding this WAL object
// Close the last file
closeCurrFile();
LOG(INFO) << idStr_ << "~FileBasedWal, dir = " << dir_;
}
// FileBasedWal 对象直到上面的所有FileBasedWalIterator都释放后,其才会调用析构函数,
// 如果继承enable_shared_from_this,你在一个类方法中无法完成这一步: 返回一个FileBasedWalIterator,该FileBasedWalIterator的参数为FileBasedWal 的shared_ptr智能指针
std::unique_ptr<LogIterator> iterator(LogID firstLogId,
LogID lastLogId) {
return std::make_unique<FileBasedWalIterator>(shared_from_this(), firstLogId, lastLogId);
}
};
class FileBasedWalIterator final : public LogIterator {
public:
// The range is [startId, lastId]
// if the lastId < 0, the wal_->lastId_ will be used
FileBasedWalIterator(std::shared_ptr<FileBasedWal> wal,
LogID startId,
LogID lastId = -1);
;
virtual ~FileBasedWalIterator();
LogIterator& operator++() override;
bool valid() const override;
LogID logId() const override;
private:
// Holds the Wal object, so that it will not be destroyed before the iterator
std::shared_ptr<FileBasedWal> wal_;
};
int main() {
std::unique_ptr<FileBasedWalIterator> iter1;
std::unique_ptr<FileBasedWalIterator> iter2;
{
std::shared_ptr<FileBasedWal> wal(new FileBasedWal(....));
iter1 = wal->iterator(...);
iter2 = wal->iterator(...);
// 作用域推出后,wal并不会被析构,因为iter对其进行了引用
}
iter其它操作
iter1,iter2都析构后,wal才会析构
}
网友评论