C++编程实践—临时对象的使用

张开发
2026/4/14 19:22:25 15 分钟阅读

分享文章

C++编程实践—临时对象的使用
一、例程引入看下面的一个简单例子#includetuple#includestringvoidsetData(conststd::tuplestd::string,std::stringdata){}setData(std::tuplestd::string,std::string{price,count});在上面的代码中创建一个临时的tuple对象用来向setData函数中传递数据这种例子看起来是不是觉得有些别扭对别扭就对了。二、临时变量在实际的开发中如果在参数传递中使用临时变量特别是临时对象这种变量很可能有一些意想不到的效果。所谓临时对象非常好理解就是一个生命周期很短只用来处理临时的一些数据的对象。一般常见于隐式对象的转换、中间结果、字符串拼接以及返回值优化等等更具体可以参看前面的“临时对象”文章。三、临时对象的作用其时临时变量中对象特别是复杂的对象可能更形象的描述下面的作用。对于很多开发者来说可能每天都在不断的使用各种形式的临时对象而且很多时候对临时对象非常“痛恨”。因为它可能增加资源的消耗大对象的拷贝和性能的降低。但这不意味着临时变量没有任何可取之处。相反如果应用得当临时变量会有着相当亮眼的表现之处。下面分析一下临时变量的几个重要场景无需命名代码清晰最典型的应用就是在写单元测试时不必要为每个函数的参数传递声明变量代码清晰可控。或者类似的对传递的参数不考虑更高层次的应用都可以直接使用临时变量。比如前面的代码示例。借助const延长生命周期C标准中规定了临时变量可以借助const引用来实现生命周期的延长一直到这个引用失效为止。这可以为开发者提供一些可以利用的场景intmain(){conststringsstring(hello) world;coutsendl;// 安全临时string的生命周期被延长}使用移动语义提高性能在使用一些大的临时对象时如果使用移动语义可能性能会更好。voidsetData(conststd::vectorstd::stringbuf){}setData(std::vectorstd::string{...});返回值优化这个在前面分析过如果临时变量作为返回值可能编译器会对其进行优化即RVO。比如下面的代码std::stringtestTmp(){return{abcd};}intmain(){std::string stestTmp();}其实临时变量在新的C标准后已经能够起到了更大的作用。特别是移动语义的出现更是如此。大家有兴趣可以看一看STL库中向量等的empalce_back函数的内部实现。结合临时变量可能会理解的更深入。下面看两个反面的例子//第一种conststd::stringf(conststd::strings){returns;}conststd::stringrf(std::string(x));//第二种conststd::stringg(){returnstd::string(x);}这两种情况在运行时都没有问题。但没有问题就代表这种写法是正确的么其实它仍然是UB行为。但为什么UB行为中它却跑出来正常的结果呢。简单说明一下上面的代码中临时变量的内存块很小对象虽然已经释放但内存的管理机制并不会将其回收并清零所以马进行访问其结果仍然是正确的。另外特别针对string经常有前面分析的sso即小对象处理。它往往直接在string对象内部分配即栈空间上。短时间内栈并不会被污染所以其结果可能仍然是正确的。四、应用的注意点使用临时对象达到开发者的目的也需要注意一些问题必须提供良好的构造包括移动构造函数能够兼容全面的参数类型和数量设计中需要保证可以接收临时对象如使用const 来进行参数传递保持设计的一致性和连续性为临时对象提供全面安全的支持还是那句话任何一项技术只有应用到了合适的场景下才会发挥其应有的长处。否则可能带来相反的后果给项目造成严重的后果。五、总结提升性能和效率的一个重要方式就是减少中间结果也就是临时对象的产生。毕竟多一层就一项开销这对于C这种视效率和性能如生命的语言更是如此。所以对于临时对象的各种应用机制和消除机制开发者要心里门儿清这样才能化废为宝零成本抽象。

更多文章