如何从接口实现中使用 shared_ptr

How to use a shared_ptr from interface implementation

假设 DoSomething 方法是接口的实现。我无法更改其签名。 DoSomething 如何使用第二个构造函数实例化 MyClass2 并提供指向 MyClass 的当前实例(不是副本)的智能指针?

#include <Windows.h>
#include <iostream>


class MyClass;

class MyClass2 {
public:
  std::shared_ptr<MyClass> ptr;

  MyClass2() {
    ptr = nullptr;
  }

  MyClass2(std::shared_ptr<MyClass> ptrParam) {
    ptr = std::move(ptrParam);
  }

};

class MyClass {
public:
  int value;

  MyClass() :
    value{1} {
    OutputDebugString(L"MyClass\r\n");
  }

  ~MyClass() {
    OutputDebugString(L"~MyClass\r\n");
  }

  std::shared_ptr<MyClass2> DoSomething() {
    return std::make_shared<MyClass2>();
  }

};

int main() {
  auto ptr = std::make_shared<MyClass>();
  auto ptr2 = ptr->DoSomething();
}

如果 DoSomething 可以访问指向 MyClass 实例的智能指针,则此操作的唯一方法是。您不能在 MyClass 中放置 shared_ptr,因为那样会产生引用循环,造成内存泄漏。

不过,还有另外一种智能指针:weak_ptr。它几乎就是为这个目的而设计的:当你需要一个智能指针,但又不想创建引用循环时。

class MyClass {
public:
  int value;
  std::weak_ptr<MyClass> selfReference;

  MyClass() :
    value{1} {
    OutputDebugString(L"MyClass\r\n");
  }

  ~MyClass() {
    OutputDebugString(L"~MyClass\r\n");
  }

  void giveSelfReference(std::shared_ptr<MyClass>& sr) {
    selfReference = sr;
  }

  std::shared_ptr<MyClass2> DoSomething() {
    return std::make_shared<MyClass2>(selfReference.lock());
  }

};

那么,main 看起来像:

int main() {
  auto ptr = std::make_shared<MyClass>();
  ptr->giveSelfReference(ptr);
  auto ptr2 = ptr->DoSomething();
}

编辑:有评论推荐 std::enable_shared_from_this<T>::shared_from_this,我对此并不熟悉,但它看起来是我的解决方案的更优雅版本。