c++ - 即使在 std::shared_ptr 拥有之后,shared_from_this 还是空的 _M_weak_this

标签 c++ c++11 vector stl shared-ptr

我在 A 中存储了一个类(我们称它为 std::vector )使用 C++ 智能指针(因此 vector 签名为 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;
}

出于某种原因,这会抛出一个 std::bad_weak_ptr ,经过检查我注意到 a ,无论出于何种原因,都有一个 _M_weak_this等于 0x0 , 或 NULL .因为我已经创建了一个有效的 std::shared_ptr引用对象,它不应该是空的。

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

我做错了什么?

最佳答案

问题似乎是因为您是从 enable_shared_from_this 私有(private)继承的

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

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

解决方案是公开继承。

class A :  public std::enable_shared_from_this<A> {
    //...
};

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

关于c++ - 即使在 std::shared_ptr 拥有之后,shared_from_this 还是空的 _M_weak_this,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47772167/

相关文章:

c++ - vector::erase 导致奇怪的行为

c++ - 如何在没有其他变量的情况下获得当前位置?

c++ - 数组指针算术 - 合法和未定义的行为

C++删除数组崩溃

c++ - 如何在 C++ 中检测/捕获 -1.#IND

c++ - 实现匿名元函数 (Lambdas) 的简便方法

c++ - 声明适用于 auto 但不是通过显式声明类型?

multithreading - C++ std::mutex和Windows CreateMutex有什么区别

c++ - 开始前缺少模板参数

c++ - 递归取消引用指针