C++中不同类初始化后PerspectiveCamera类成员变量值异常变化问题
问题根因
你遇到的是C典型的**悬空引用(Dangling Reference)**问题,和Renderer的初始化逻辑无关,问题出在PerspectiveCamera对象的构造阶段:PerspectiveCamera的center、forward、up三个成员均为引用类型,你构造pcam2时传入的是Point(0,0,0)、Vector(0.5f, 0.5f, 0.3f)、Vector(0,0,1)三个临时对象。
C语法规定,除非特殊声明,临时对象的生命周期仅持续到它所在的完整表达式执行结束:也就是PerspectiveCamera pcam2(...)这一行代码执行完成后,三个临时对象就会被销毁,对应的内存空间会被标记为可回收,后续可能被其他程序数据覆盖。
此时pcam2的三个引用成员就变成了指向已释放内存的悬空引用,访问这些成员时就会读到不可预期的垃圾值,你在初始化r12时观测到的异常数值,本质是之前临时对象占用的内存已经被其他数据覆盖导致的。
修复方案
- 方案1(最推荐):修改
PerspectiveCamera的类定义,将center、forward、up三个成员的类型从引用改为普通值类型,直接存储对象副本,完全不依赖外部传入对象的生命周期。 - 方案2:如果业务逻辑要求必须保留引用类型的成员,需要保证传入的参数对象生命周期至少和
PerspectiveCamera对象的生命周期一致,示例代码如下:
// 先构造生命周期和pcam2匹配的局部对象 Point cam_center(0, 0, 0); Vector cam_forward(0.5f, 0.5f, 0.3f); Vector cam_up(0, 0, 1); // 用局部对象而非临时对象初始化pcam2 PerspectiveCamera pcam2(cam_center, cam_forward, cam_up, pi * 0.9f, pi * 0.9f); Renderer r12(&pcam2, 0);
- 方案3:如果使用C++11及以上版本,可将类成员定义为右值引用,可延长绑定的临时对象生命周期到类对象的生命周期,但该方案容易引入其他隐性的生命周期问题,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Jane Cherrytree
相关产品推荐
相关产品推荐

