20协助完成“返回值优化(RVO)”:
RVO:return value optimization 返回值优化
利用函数的return点消除一个局部临时对象
防止函数返回对象
- 既然函数返回对象无法避免临时对象的产生,那就防止函数返回对象(改为返回指针或引用)
- 但是此方法易产生危险或者不合理的行为
- 例如:返回指针就要考虑是否应该删除此函数返回指针,删除了易造成内存泄漏(因为常被忽略或者遗忘)。
- 例如:返回引用,这个引用指向局部对象,局部对象返回时自动被销毁,引用却指向一个不在存货的对象。
// 错误写法
const Rational& operator*(const Rational & lhs, const Rational & rhs)
{
Rational res(lhs.a() * rhs a(), lhs.b() * rhs.b());
return res;
}
函数如果返回对象
- 函数如果返回对象,因为以值传递的方式返回对象,背后隐层的构造和析构成本都是无法消除的。
- 从效率的眼光:我们不应该在乎函数返回了一个对象,应该在乎那个对象的成本,如果成本为0,生产多少个都无所谓
RVO(返回值优化)
- 通过特殊的写法,使编译器消除临时对象的成本,返回所谓的
构造参数
以取代对象
const Rational operator*(const Rational & lhs, const Rational & rhs)
{
return Rational(lhs.a() * rhs a(), lhs.b() * rhs.b());
}
写法看似产生一个Rational
临时对象并为它的构造和析构付出代价,函数复制此临时对象作为返回值又付出了构造和析构的代价,但是其实编译器将临时对象优化,使他们全都不存在。编译器优化过程:将return表达式所定义的对象构造于一个命名对象
为c
的内存中,也就是说没有任何临时对象需要被产生出来,取而代之你只需要一个构造产生c
的代价。最优写法:使用inline消除调用函数的额外开销
incline const Rational operator*(const Rational & lhs, const Rational & rhs)
{
return Rational(lhs.a() * rhs a(), lhs.b() * rhs.b());
}
C++还有一个移动构造函数,专门用来对临时值,将亡值的处理。。。。。。
class A
{
public:
A() { cout << "构造" << endl; }
A(const A& rhs) { cout << "构造" << endl; }
A(A&& rhs)noexcept { cout << "移动构造" << endl; }
~A()noexcept { cout << "析构" << endl; }
};
const A func()
{
A a; //a是一个临时对象
return a; //没有优化处理,先构造a,然后移动构造,析构两次
}
const A func2()
{
return A(); //返回值优化处理,构造一次,析构一次,这是一个无名对象
}
Comments NOTHING