笑看天下无敌手 发表于 2024-6-17 15:19:35

何时/如何使用 std::enable_shared_from_this<T>?

要点回首


[*]继承自 std::enable_shared_from_this 的类可以或许在其自身实例中通过 std::shared_from_this 方法创建一个指向自己的 std::shared_ptr 智能指针。
[*]从一个裸指针创建多个 std::shared_ptr 实例会造成严峻的后果,其活动是未定义的。
[*]std::enable_shared_from_this 现实包含了一个用于指向对象自身的 std::weak_ptr 指针。

引言

本文先容 std::enable_shared_from_this 及 std::shared_from_this 的基本概念和使用方法。


定义 "std::enable_shared_from_this"

以下内容是 cppreference.com 上关于 std::enable_shared_from_this 的定义和分析:
Defined in header < memory >
template< class T > class enable_shared_from_this; (since C++11)
std::enable_shared_from_this allows an object t that is currently managed by a std::shared_ptr named pt to safely generate additional std::shared_ptr instances pt1, pt2, ... that all share ownership of t with pt.
Publicly inheriting from std::enable_shared_from_this provides the type T with a member function shared_from_this. If an object t of type T is managed by a std::shared_ptr named pt, then calling T::shared_from_this will return a new std::shared_ptr that shares ownership of t with pt.
简单来说就是,继承自 std::enable_shared_from_this 的类可以或许在其自身实例中通过 std::shared_from_this 方法创建一个指向自己的 std::shared_ptr 智能指针。
想要理解 std::enable_shared_from_this,起首得知道为什么需要 std::enable_shared_from_this,请看下文。

使用 "std::enable_shared_from_this"

为什么需要 std::enable_shared_from_this? 我们从一个例子讲起,会更轻易一些。
假定有一个类 Processor, 它的作用是异步处理数据并且存储到数据库。当 Processor 吸收到数据时,它通过一个定制的 Executor 范例来异步处理数据:
class Executor {
public:
//Executes a task asynchronously
void
execute(const std::function<void(void)>& task);
//....
private:
/* Contains threads and a task queue */
};

class Processor {
public:
//...
//Processes data asynchronously. (implemented later)
void processData(const std::string& data);

private:
//Called in an Executor thread
void doProcessAndSave(const std::string& data) {
    //1. Process data
    //2. Save data to DB
}
//.. more fields including a DB handle..
Executor* executor;
};Client 类包含了一个 std::shared_ptr 实例,Processor 从 Client 类吸收数据:
class Client {
public:
void someMethod() {
//...
processor->processData("Some Data");
//..do something else
}
private:
std::shared_ptr<Processor> processor;
};以上示例中,Executor 是一个线程池,用于执行任务队列中的任务。
在 Processor::processData 中,我们需要通报一个(指针)函数(lambda 函数)给 Executor 来执行异步操作。该 lambda 函数调用 Processor::doProcessAndSave 以完成现实的数据处理工作。因此,该 lambda 函数需要捕捉一个 Processor 对象的引用/指针。我们可以如许做:
void Processor::processData(const std::string& data) {
executor->execute(() { //<--Bad Idea
   //Executes in an Executor thread asynchronously
   //'this' could be invalid here.
   doProcessAndSave(data);
});
}self = shared_from_this() 通报的是一个正当的 std::shared_ptr 实例,正当的类 Processor 对象的引用。

深入 "std::enable_shared_from_this" 内部

std::enable_shared_from_this 的实现雷同:
void good() {
auto p{new int(10)}; //p is int*
std::shared_ptr<int> sp1{p};
//Create additional shared_ptr from an existing shared_ptr
auto sp2{sp1}; //OK. sp2 shares control block with sp1
}enable_shared_from_this 包含了一个 std::weak_ptr 指针,这正是函数 shared_from_this 返回的内容。注意,为什么不是 std::shared_ptr? 因为对象包含自身的计数引用会导致对象永远不被释放,从而发生内存泄漏。上述代码中 weak_this 会在类对象被 std::shared_ptr 引用时赋值,也就是std::shared_ptr 实例的构造函数中赋值,这也是为什么类 enable_shared_from_this 的最后,其被声明成为了 shared_ptr 的友元。

总结

到此,关于 std::enable_shared_from_this 的先容就竣事了。

引用

https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
https://www.nextptr.com/tutorial/ta1414193955/enable_shared_from_this-overview-examples-and-internals

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 何时/如何使用 std::enable_shared_from_this<T>?