enable_shared_from_this
学习笔记
从字面意思来看,就是让对象能够将其 this
指针以智能指针 shared_ptr
的形式进行获取,那么能否直接以智能指针的形式来获取对象的 this
指针吗?
1.用智能指针封装返回 this
指针
#include <iostream>
#include <memory>
class A {
public:
A() {
std::cout << "constructor." << std::endl;
}
~A() {
std::cout << "destructor." << std::endl;
}
std::shared_ptr<A> getSharedA() {
return std::shared_ptr<A>(this);
}
};
int main() {
std::shared_ptr<A> ptr(new A());
std::shared_ptr<A> ptr_get = ptr->getSharedA();
std::cout << "ptr.use_count(): " << ptr.use_count() << std::endl;
std::cout << "ptr_get.use_count(): " << ptr_get.use_count() << std::endl;
return 0;
}
运行结果如下:
free(): double free detected in tcache 2
constructor.
ptr.use_count(): 1
ptr_get.use_count(): 1
destructor.
destructor.
Process finished with exit code 134 (interrupted by signal 6:SIGABRT)
从输出结果可以看到,调用一次构造函数,却调用了两次析构函数,这明显不正确。
2.enable_shared_from_this
enable_shared_from_this
能解决安全获取 this
指针问题,使用方法如下:
#include <iostream>
#include <memory>
class A : public std::enable_shared_from_this<A> {
public:
A() {
std::cout << "constructor." << std::endl;
}
~A() {
std::cout << "destructor." << std::endl;
}
std::shared_ptr<A> getSharedA() {
return shared_from_this();
}
};
int main() {
std::shared_ptr<A> ptr(new A());
std::shared_ptr<A> ptr_get = ptr->getSharedA();
std::cout << "ptr.use_count(): " << ptr.use_count() << std::endl;
std::cout << "ptr_get.use_count(): " << ptr_get.use_count() << std::endl;
return 0;
}
enable_shared_from_this
内部为 weak_ptr
,当 ptr
被定义为 shared_ptr
后,ptr
的引用计数为1(weak_ptr
不会增加引用计数),再通过 shared_from_this
获取内部 this
指针的智能指针,则 ptr
的引用计数变为2。
编译输出为:
constructor.
ptr.use_count(): 2
ptr_get.use_count(): 2
destructor.
Process finished with exit code 0
3.源码解析
template<class _Tp>
class enable_shared_from_this {
mutable std::weak_ptr<_Tp> __weak_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() {}
public:
std::shared_ptr<_Tp> shared_from_this() { return std::shared_ptr<_Tp>(__weak_this_); }
std::shared_ptr<_Tp const> shared_from_this() const { return std::shared_ptr<const _Tp>(__weak_this_); }
template<class _Up> friend class shared_ptr;
};
enable_shared_from_this
类的内部有个 _Tp
类型 week_ptr
指针,调用 shared_from_this
成员函数便可获取到目标类型 _Tp
类型智能指针。