参考链接1 [参考链接2](C++智能指针enable_shared_from_this - 掘金 (juejin.cn))
如何获取对象的this指针
一般来说不建议直接返回this指针,如果返回的this指针保存在外部的一个局部/全局变量(同share_ptr不建议保存get()返回的裸指针,避免share_ptr引用计数为0析构后外部继续访问原裸指针),当对象已经被析构,但外部变量不知道被析构了,继续使用该指针就会导致程序崩溃。
#include <iostream> #nclude <memory>
class Demo {
public:
Demo() {
//构造;
std::cout << "Demo::Demo()\n";
}
~Demo() {
//析构;
std::cout << "Demo::~Demo()\n";
}
std::shared_ptr<Demo> getShareObj() {
return std::shared_ptr<Demo>(this);//使用智能指针返回this指针
}
};
int main(){
std::shared_ptr<Demo> p1 = std::make_shared<Demo>();
std::shared_ptr<Demo> q1 = p1->getShareObj();
std::cout << "p1 count = " << p1.use_count() << std::endl;//use_count == 1 std::cout << "q1 count = " << q1.use_count() << std::endl;//use_count == 1 return 0;
}
//结果:程序异常结束:p1与q1 分别调用了一次析构
//enable_shared_from_this可解决安全的获取this指针问题
std::enable_shared_from_this方法
enable_shared_from_this源码(简化版)
template <class T>
class enable_shared_from_this {
protected:
enable_shared_from_this() noexcept {}
enable_shared_from_this(enable_shared_from_this const &) noexcept {}
enable_shared_from_this &operator=(enable_shared_from_this const &) noexcept { return *this; }
~enable_shared_from_this() noexcept {} public: std::shared_ptr<T> shared_from_this() {
if (auto p = weak_this_.lock()) {
return std::shared_ptr<T>(p);
} else {
throw std::bad_weak_ptr();
}
}
std::shared_ptr<T const> shared_from_this() const {
//lock()检测弱引用是否有效
if (auto p = weak_this_.lock()) {
return std::shared_ptr<T const>(p);
} else {
throw std::bad_weak_ptr();
}
}
std::weak_ptr<T> weak_from_this() noexcept {
return weak_this_;
}
std::weak_ptr<T const> weak_from_this() const noexcept {
return weak_this_;//返回指向自身的弱引用
}
private:
mutable std::weak_ptr<T> weak_this_; //用于保存指向自身的弱引用std::weak_ptr实例,使对象能够在需要时生成一个共享引用 };
#### enable_shared_from_this原理
std::enable_shared_from_this是一个模板类,用于帮助类对象生成一个与其共享的std::shared_ptr实例,通常在类内部保存一个指向自身的std::shared_ptr,以便在需要时生成一个共享引用。
通过继承 std::enable_shared_from_this 的类对象,在需要生成共享引用时,调用 shared_from_this() 成员函数,该函数会返回一个指向自身的 std::shared_ptr 实例。这样就可以确保在对象被销毁之前,仍然有一个有效的共享引用存在。
在底层实现中使用弱引用的概念,即在类对象内部保存了一个指向自身的弱引用 std::weak_ptr 实例。当调用 shared_from_this() 成员函数时,会先检查这个弱引用是否有效,如果有效则返回一个指向自身的 std::shared_ptr 实例,否则返回一个空的 std::shared_ptr。这样就能够确保在对象被销毁时,所有共享引用也会被正确地释放,避免出现悬空指针的情况。
用enable_shared_from_this()返回this指针
class DemoThis :public std::enable_shared_from_this<DemoThis> {
public:
DemoThis() {
std::cout << "DemoThis::DemoThis()\n";
}
~DemoThis() {
std::cout << "DemoThis::~DemoThis()\n";
}
std::shared_ptr<DemoThis> getShareObj() {
return shared_from_this();
}
};
int main(){
std::shared_ptr<DemoThis> p1 = std::make_shared<DemoThis>();//P1不使用裸指针而使用智能指针,避免delete引用this指针不安全的风险,这里shared_ptr引用计数为1(weak_ptr不增加引用计数);
std::shared_ptr<DemoThis> q1 = p1->getShareObj();
std::cout << "p1 count = " << p1.use_count() << std::endl; //use_count == 2
std::cout << "q1 count = " << q1.use_count() << std::endl; //use_count == 2 return 0;
}