即使在std :: shared_ptr拥有所有权后,shared_from_this也有空的_M_weak_this

Cal*_*Bit 5 c++ stl vector shared-ptr c++11

Astd::vector使用C ++智能指针(因此向量符号为std::vector<std::shared_ptr<A>>)中存储一个类(我们称之为)。

#include <iostream>
#include <memory>
#include <vector>

class A : std::enable_shared_from_this<A> {
public:
  void doWork();
  std::shared_ptr<A> getSharedRef();
};

void A::doWork() { std::cout << "Working..." << std::endl; }

std::shared_ptr<A> A::getSharedRef() { return shared_from_this(); }

class AManager {
  static std::vector<std::shared_ptr<A>> aList;

public:
  static void init(); // safety because statics
  static void doLotsOfWork();
  static std::shared_ptr<A> createA();
};

std::vector<std::shared_ptr<A>> AManager::aList;

void AManager::init() { aList = std::vector<std::shared_ptr<A>>{}; }

void AManager::doLotsOfWork() {
  for (auto a : aList) {
    a->doWork();
  }
}

std::shared_ptr<A> AManager::createA() {
  std::shared_ptr<A> a = std::make_shared<A>();

  aList.push_back(a);
  return a->getSharedRef(); // <----- EXCEPTION
}

int main() {
  AManager::init();
  AManager::createA();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,这引发了std::bad_weak_ptr,并且经检查,我注意到a,无论出于何种原因,其均_M_weak_this等于0x0NULL。由于我已经创建了一个有效的std::shared_ptr引用对象,因此它不应为空。

此外,我知道没有发生内存损坏的情况,因为A(带有变量)在其地址处是完整的。

我究竟做错了什么?

And*_*dyG 6

问题似乎是因为您是从私下继承 enable_shared_from_this

shared_from_this要求“ enable_shared_from_this<T>应是的可访问基类” T。(根据[util.smartptr.enab])

通过私有继承,无法访问基类,因此违反了前提条件。我认为这意味着未定义的行为。Clang和GCC都抛出异常。

解决方案是公开继承。

class A :  public std::enable_shared_from_this<A> {
    //...
};
Run Code Online (Sandbox Code Playgroud)

*在C ++ 17中,措词似乎已移至[util.smartptr.shared.const],但要求基本相同。