c++ - 因shared_ptr而崩溃

标签 c++ pointers c++11 shared

有人可以向我解释一下为什么会在这里崩溃吗?

#include <memory>
#include <functional>

struct Teacher : std::enable_shared_from_this<Teacher> {
    struct Timetable;
    std::shared_ptr<Timetable> timetable;
    Teacher (int n) : timetable(std::make_shared<Timetable>(*this, n)) {}
};

struct Period {
    std::shared_ptr<Teacher> teacher;
    Period (const std::shared_ptr<Teacher>& t) : teacher(t) {}
};

struct Teacher::Timetable {
    Teacher& teacher;
    std::shared_ptr<Period> homeForm;
    Timetable (Teacher& t, int n) : teacher(t),  // Assume something is done with n.
        homeForm( std::make_shared<Period>(teacher.shared_from_this()) ) {}  // Crashes.
//      homeForm( std::make_shared<Period>(std::shared_ptr<Teacher>(&teacher)) ) {}  // Also crashes.
};

int main() {
    std::shared_ptr<Teacher> teacher = std::make_shared<Teacher>(3);
}

不是 teacher.shared_from_this()std::shared_ptr<Teacher> teacher起允许在这里已经是shared_ptr了吗?如果没有,我该如何初始化homeForm正确吗?

最佳答案

问题是您的代码调用 shared_from_this之前std::shared_ptr<Teacher>已全面建成。从某种程度上来说,Teacher 是有道理的。子对象必须在智能指针完全构造之前构造。

如果你像这样改变代码,

struct Teacher : std::enable_shared_from_this<Teacher> {
    struct Timetable;
    std::shared_ptr<Timetable> timetable;
    Teacher() {}
    void init(int n) { this->timetable = std::make_shared<Timetable>(*this, n); }
};

// Everything else unchanged

int main() {
    std::shared_ptr<Teacher> teacher = std::make_shared<Teacher>();
    teacher->init(3);
}

它会运行良好。

请注意,我不建议将此作为重构。构造函数应尽可能完全初始化对象。看看你的代码,在我看来,你可能想考虑更激进地重新构建它。您真的需要所有这些交叉引用共享指针吗?

关于c++ - 因shared_ptr而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35832798/

相关文章:

C++ - 方法实现取决于是否设置了成员引用变量

python - GLIBC_2.14 未找到,如果我不是 root,我该怎么办

c++ - 无法解析类型 'std::default_random_engine'

c++ - 无法在 Visual Studio 2017 中使用 QT

c++ - C++中的转换优先级

c++ - 如何使用 initializer_list 创建结构的 C++ <array>?

c++ - 如何在 C++ 中计算 3 位小数精度的圆周率?

c++ - 销毁具有指针值的 map 的正确方法

c++ - 为什么指向 int 的指针转换为 void* 而指向函数的指针转换为 bool?

c++ - STL Map<string, > 与 LLVM 库冲突