传递std::shared_ptr给子类触发Segmentation fault问题求助
问题根因分析
1. 默认构造函数触发段错误的核心原因
C++ 中类成员的初始化顺序严格按照类定义中声明的先后顺序执行,和初始化列表的书写顺序完全无关:
- C0 类的成员声明顺序为先定义
std::shared_ptr<Dbg> dbg,再定义C1 c1Inst - 调用默认构造
C0()时执行逻辑如下:- 首先初始化
dbg:std::shared_ptr默认构造为空指针 - 再执行初始化列表的
c1Inst(dbg):把当前为空的dbg传入C1构造函数,C1内部的dbg直接被初始化为空指针 - 最后才执行构造函数体内的
dbg = std::make_shared<Dbg>(false):这一步仅修改C0自身的dbg指针,已经传递给C1的空指针不会同步更新
- 首先初始化
- 后续调用
c1Inst.print()时,访问空的dbg指针执行成员函数,直接触发段错误。
2. 你修改后的带参构造仍存在设计缺陷
你修改main函数后调用的C0带参构造,仅初始化了C0自身的dbg指针,没有将该指针传递给内部的c1Inst实例,因此c1Inst会调用自身默认构造函数,生成一个独立的、enabled=false的Dbg实例,既不符合共享同一个日志实例的需求,也不会输出预期的日志内容。
修复方案
仅需调整C0两个构造函数的初始化逻辑即可:
class C0 { protected: std::shared_ptr<Dbg> dbg; C1 c1Inst; public: // 默认构造:先初始化dbg,再传递给c1Inst C0() : dbg(std::make_shared<Dbg>(false)), c1Inst(dbg) {} // 带参构造:将传入的dbg同时传递给内部c1Inst C0(std::shared_ptr<Dbg> dbg) : dbg(dbg), c1Inst(dbg) {} void run() { c1Inst.print(); } };
修改后两种构造方式都能保证C0和内部C1实例共享同一个Dbg对象,不会出现空指针,也符合日志实例全局复用的设计目标。
内容的提问来源于stack exchange,提问作者jkang
相关产品推荐
相关产品推荐

