C++中能否通过自引用方法传递未命名临时对象给非const引用?
问题:临时StreamRead对象传递给非const引用参数的合法性
我有一个表示文件的StreamRead类,希望将其传递给Bitmap等类的构造函数。但Bitmap的构造函数接收非const引用类型的StreamRead参数(因StreamRead的读取操作会改变文件位置,无法设为const),无法直接传入未命名临时对象。我找到三种解决方式,目前采用第三种:给StreamRead添加返回自身引用的pass()方法,通过链式调用传入Bitmap构造函数,但不确定该写法在C++中是否定义良好,担心临时对象提前销毁导致悬垂引用。
原始非法代码示例
Bitmap::Bitmap(StreamRead & in) { // "in" 不能是const,因为StreamRead的读取操作会改变文件位置 ... } int main() { Bitmap image(StreamRead("filename.png")); // 非法 }
修改后的代码示例
StreamRead & StreamRead::pass() { return *this; } int main() { // 合法,但这样写是否定义良好? Bitmap image(StreamRead("filename.png").pass()); }
解答
这种写法是定义良好且完全安全的。
根据C++标准,临时对象的生命周期会延续到包含它的完整表达式结束时。这里StreamRead("filename.png")是一个临时对象,调用它的pass()方法返回自身引用后,该临时对象会一直存活到Bitmap image(...)这个构造表达式执行完毕——也就是Bitmap的构造函数完全执行完成之后,才会被销毁。
在Bitmap构造函数运行期间,临时StreamRead对象始终处于有效状态,不会出现悬垂引用的问题。
另外补充两种常见的替代解决思路供参考:
- 思路一:创建具名对象后传入
int main() { StreamRead sr("filename.png"); Bitmap image(sr); // 合法 } - 思路二:将构造函数参数改为右值引用
Bitmap::Bitmap(StreamRead&& in) { // 可正常调用in的非const成员函数 ... } int main() { Bitmap image(StreamRead("filename.png")); // 合法 }
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

