1、首先,确认什么是临时对象。在swap方法中,建立一个对象temp,程序员往往把temp称为临时对象。实际上,temp是个局部对象。C++中所谓的临时对象是不可见的,产生一个non-heap对象,并且没有命名,便是一个临时对象。
2、临时对象的来源有:隐式类型转换,方法返回值,抛出异常的时候。
3、隐式类型转换:在初始化或者赋值的过程中,如果类型不匹配,需要一个适配的临时对象,编译器会构造这个临时对象,使调用成功。
注意:这种适配,只能执行一次,不能执行多次。为什么?假如可以执行多次,从一个对象到另一个对象,存在很多转换路径,编译器不可能找出所有的路径。就算可以找出所有的路径,存在多条转换路径,到底走哪一条呢?
4、隐式类型转换产生的临时对象不可修改,也就是const。不能赋值给non-const引用。为什么?
假设可以赋值给non-const引用,程序员修改这个引用,企图修改原数据,但实际上修改的是临时对象,这与程序员的期望不一致。因此,规定临时对象是const。
5、方法返回值是个临时对象,它没有名称,就是一个返回值。思考,为什么需要这个临时对象?
方法内的局部对象在调用完成后,被销毁。因此,从这个局部对象到调用端,必须有一个临时对象,才能传递过去。
6、方法返回值往往是const对象,这个为了,禁止客户对方法返回值进行赋值。
7、抛出异常的时候,从抛出端到catch语句,必须有一个临时对象才能传递过去,需要注意的是,这个临时对象可以修改。
8、临时对象造成效率低,因为必须承担临时对象的构造和析构成本。因此,应该避免产生临时对象。
对于隐式类型转换:两种方法,使隐式转换不再发生,或者隐式转换不再需要。
对于方法返回值:使用一个技巧,返回值优化RVO(Return Value Optimization),让编译器进行优化。
对于抛出异常的时候:从抛出异常到catch语句,这个临时对象必不可少,当然编译也可能进行优化。需要注意的是,catch语句中应该使用by reference,避免再一次的copy构造,同时避免对象切割。