如何在构造函数完成后为类的引用成员赋值?
问题分析与解决方案
你遇到的核心问题是引用成员的生命周期管理错误,导致后续操作出现悬空引用,触发了vector subscript out of range异常(本质是访问了已销毁对象的内存)。
为什么原来的代码会出错?
你在OtherClass的构造函数初始化列表里写了m_class(Class()),这里的Class()是一个临时对象,它的生命周期只到构造函数执行完毕为止。构造函数结束后,这个临时对象被销毁,你的m_class引用就变成了悬空引用——指向一块已经被释放的内存。之后调用SetData里的m_class = Class(data3),本质是在操作一个不存在的对象,这种未定义行为就会导致glm向量(内部依赖连续内存)出现下标越界之类的异常。
而且C++里引用的特性是一旦绑定对象就不能再改变指向,所以你想在构造后“设置引用”的思路本身就行不通,引用做不到这一点。
针对你的需求,推荐两种解决方案
方案1:改用智能指针代替引用(最灵活)
如果需要延迟初始化对象,指针是更合适的选择,用std::unique_ptr可以自动管理内存,避免泄漏:
#include <memory> class OtherClass { public: // 构造时初始化指针为空 OtherClass() : m_class(nullptr) {} inline void SetData(int data1, int data2) { // 替换成你的实际计算逻辑 int data3 = data1 + data2; // 创建新的Class对象并赋值给指针 m_class = std::make_unique<Class>(data3); } // 调用Class的成员函数时,先检查指针是否有效 void CallClassMethod() { if (m_class) { m_class->YourClassMethod(); // 替换成你要调用的函数 } } protected: private: std::unique_ptr<Class> m_class; // 用智能指针替代引用 };
子类ExClass可以正常调用SetData,完全符合你的需求:
class ExClass : public OtherClass { public: ExClass(float d1, float d2, ...) { // 根据传入的参数计算data1、data2 int calc_data1 = static_cast<int>(d1 * 2); // 示例计算 int calc_data2 = static_cast<int>(d2 * 3); SetData(calc_data1, calc_data2); } };
方案2:将Class直接作为成员变量(如果不需要外部对象)
如果Class对象不需要从外部传入,直接把它作为OtherClass的成员(而非引用),这样就可以在SetData里直接赋值:
class OtherClass { public: // 构造时默认初始化Class成员 OtherClass() {} inline void SetData(int data1, int data2) { int data3 = data1 + data2; // 你的计算逻辑 m_class = Class(data3); // 直接赋值给成员对象,完全合法 } void CallClassMethod() { m_class.YourClassMethod(); // 直接调用成员函数 } protected: private: Class m_class; // 直接作为成员,而非引用 };
这种方案更简单,不需要处理指针,适合Class对象只属于OtherClass的场景。
关键提醒
- 永远不要让引用绑定到临时对象,除非你能保证临时对象的生命周期覆盖引用的使用周期。
- 如果必须延迟初始化,优先考虑智能指针,手动管理裸指针容易出现内存泄漏或悬空指针问题。
内容的提问来源于stack exchange,提问作者Freddy C.
相关产品推荐
相关产品推荐

