在上C++课的时候,老师会提到C++函数传值和传引用的区别,特别会强调传值时,会产生一次拷贝。如果返回值,那么返回时也会产生一次拷贝。如果传值不是基本数据类型,而是一个很大的类、或者结构,就会造成额外的内存调用,影响效率。
MyBigClass foo(MyBigClass a)
{
return a;
}
C++11以来,这种说法已经不能完全成立了。C++11标准规定编译器可以做出一定的优化不去调用拷贝构造函数。在gcc和clang里,这个优化可以通过-felide-constructors来实现。相反地,通过使用-fno-elide-constructors,就可以关闭这个编译器优化,该拷贝的还是会拷贝。
需要特别注意的是,即使拷贝构造函数、移动构造函数有特殊的定义,这个编译器优化还是会起效果。也就是说,自定义的拷贝/移动构造函数,可能因为被优化去除,所以没有按照设计执行。另外,不同的编译器可能会有不同的优化策略,导致最后出现的结果不同,在移植代码的时候要额外留心。