所谓临时对象,就是一种匿名对象,它的出现不在程序的预期之下(不会出现在你的源代码中),并且它不会产生在heap里。那么临时对象是怎么产生的呢?
-
传递某对象给一个函数,而其类型与它即将绑定上去的参数类型不同的时候。
-
值传递操作。
现在让我们仔细分析一下吧。
1.传递某对象给一个函数,而其类型与它即将绑定上去的参数类型不同的时候。
void Print(const std::string& str) {
std::cout << str.c_str();
}
int main(void)
{
char buffer[] = "jay_chou"; //字符串常量是常量字符数组
Print(buffer);
return 0;
}
以buffer作为自变量,调用string constructor 。于是Print的str参数会被绑定与此string的临时对象上(也就是说,调用编译器为我们产生临时对象,任何调用 constructor,buffer作为构造函数的实参进行传递对临时对象进行构造,最后str的参数绑定到此string临时对象身上)。当Print函数结束其生命周期时,此临时对象会被自动销毁。
2.值传递操作。
void Print(std::string str) {
std::cout << str.c_str();
}
std::string Print_() {
std::string name = "jay";
return name;
}
int main(void)
{
std::string name = "jay";
Print(name);
std::cout << Print_().c_str();
return 0;
}
通过值传递操作,通常会产生临时变量。那就让我分析一下,临时对象是怎么产生的吧? 首先编译器会为我们产生一个临时对象temp_,然后调用 constructor 对临时对象进行构造 ,这时函数会发生改变,类似与变成了 copy constructor ,通过值传递构造的对象将调用 copy constructor ,临时对象作为实参进行传递,copy constructor函数生命周期结束,l临时对象调用其析构函数进行销毁。
总而言之,临时对象可能会很毫成本,所以应该尽可能的消除它们,但是有时产出临时对象,会让我们的代码更加清晰,在有时候也是有益的。任何时候只要看到reference_to_cosnt 参数,就很可能会有一个临时对象绑定到此参数上。任何时候只要看到pass_to_value(值传递),就会产生临时对象。