有人可以向我解释为什么会在这里崩溃吗?
#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()
已经是shared_ptr,所以允许std::shared_ptr<Teacher> teacher
在这里吗?如果没有,我该如何正确初始化homeForm
?
答案 0 :(得分:2)
问题是您的代码在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);
}
它会正常运行。
请注意,我不建议将其作为重构。构造函数应尽可能完全初始化对象。看看你的代码,在我看来,你可能想要考虑重新构建一些更激进的代码。你真的需要所有这些交叉引用的共享指针吗?