MirrorYuChen
MirrorYuChen
Published on 2025-01-01 / 37 Visits
0
0

C++中`enable_shared_from_this`学习笔记

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类型智能指针。

4.参考资料


Comment