C++对值语义的支持,导致程序员一不留神就会多出一次“拷贝”的过程。既然选择了C++这种坑多开发效率又低的语言,一定是因为对于性能有比较高的需求(不追求性能,Python、JS、Java选哪个不好?),所以对于无处不在的拷贝,还是尽量避免为好。
对于避免拷贝,一般有以下两种做法:
引用,而不是拷贝
引用最初在C++中提出是为了能够更“原生”地处理运算符重载的结果,比如
这里重载的运算符[]就会返回一个引用,所以我们可以像一般变量一样对其赋值。
说回利用引用避免拷贝,一般可以检查如下三种情况:
a.临时变量
对于嵌套很深的变量,比如
如果这个变量在之后多次被用到,一般地,我们会选择用一个常量引用作为其“别名”,避免一次拷贝。
b.函数参数
函数的形参绑定到实参时,一般会将实参做一次拷贝。这时,对于那些在函数内不会被修改的参数,可以使用常量引用,避免这一次拷贝。
c.map插入
map的插入经常会被写成这样
这样的话就引入了一次拷贝。
但是实际上,map对于[]的重载保证了如果key不存在时,会自动构建一个对象,并返回其引用,所以可以这样避免拷贝:
移动,而不是拷贝
移动语义是C++11中引入的,表示资源的“窃取”、“转移”,而不是“拷贝”。它和右值引用,std::move结合,可以减少拷贝的发生。
例如:
这里依赖如下几个概念,得以实现“移动语义”,而非“拷贝/赋值语义”
因此,对于一个“后续不再使用的对象objectA”,当我们想要窃取其资源(如将其放入容器)时,可以通过std::move+右值引用+移动构造/赋值函数这一套组合拳,避免资源的无谓拷贝。
领取专属 10元无门槛券
私享最新 技术干货