c++中的临时变量

转载 2018年04月17日 13:57:42

 转自https://blog.csdn.net/joey_zengchen/article/details/1566713

https://blog.csdn.net/qq_38193597/article/details/70193742


       说到临时变量,我们大家也许都挺熟悉, 但是我自己对临时变量的理解却一直存在一个误区。通常情况下,我会把为了做某一件事情而临时创建的一个变量叫做临时变量。比如说在交换两个变量的值时,通常我们会创建第三个变量来达到我们最终的目的,而我们称之为“临时变量”。然而,大师Scott Meyers告诉我们,事实不是这么简单!

        在C/C++中,真正意义上的临时变量是看不见的,就是说它们不会出现在你的代码中,参考一下这句话(来自《More Effective C++》): True temporary objects in C++ are invisible — they don't appear in your source code. They arise whenever a non-heap object is created but not named.

        按照这种定义,我以前所理解的“临时变量”其实并不是真正意义上的临时变量,他只是我所定义的一个短命的局部变量而已。

临时变量通常在函数参数传递发生类型转换以及函数返回值时被创建。比如下面这个例子:
void uppercasify(const string& str)
{}

int main(int argc, char* argv[])
{
 char subtleBookPlug[] = "Effective C++";
 uppercasify(subtleBookPlug);  // 此处有类型转换
 return 1;
}
函数uppercasify需要const string&类型的参数,而实参类型为char *,故编译器会尝试着进行类型转换。此时一个string类型的临时变量将被创建,并用subtleBookPlug来初始化对象,最后将临时变量传给函数uppercasify。
理解了这个例子,也就能较好的理解为什么C/C++不允许为非const的引用类型创建临时变量了。比如下面这个例子:
void uppercasify(string& str)  // 参数类型改为string &
{}

int main(int argc, char* argv[])
{
 char subtleBookPlug[] = "Effective C++";
 uppercasify(subtleBookPlug);
 return 1;
}
        此时,如果创建了一个临时变量,那函数所修改的对象为临时变量,而不是用户所期待的subtleBookPlug了,从而容易引起误操作。

产生临时变量的三种情况:一:以By Value的方式传值;二:参数为const的类型。三:类型转换

一:以By Value的方式传值。
        我们都知道,引用类型和指针类型传递的都是地址,可以直接对地址中存放的数据进行操作,而以传值的方式传递参数,就会在heap中重新分配一个临时区域,将实参中的数据拷贝到临时区域中,而你对这份数据进行的任何的操作都不会影响实参的内容,因为实参跟形参只是内容相同,分别在两块不同的内存中。而引用和指针操作的是同一块内存,所以形参修改后,实参也修改了。
二:参数为const的类型。
        因为常量是不能修改,在只需要实参中的数据,而不需对实参进行修改时,或是禁止对实参进行修改时,把形参定义为const类型,系统会产生一个临时变量,就能起到保护数据的作用,如在函数strlen中,修改参数的值行吗?本来只是想得到实参的长度,结果在函数中被修改了,那得到得实参长度还是真实的吗。
        如果你程序中的数据到处都可以被修改,那是多么的可怕(所以我们讨厌全局变量),所以const还是有它存在的价值。
三:类型转换的时候会产生临时变量。
        真是糟糕啊,在用类型转换带来便利的同时,产生临时变量就是我们承担的损失。
        如将一个short类型转换成int类型,他们占用的内存不一样,如果不产生临时变量,那不就short类型和int类型占用的字节数不就一样了吗,sizeof不就坑爹了吗。
 

     C++语言禁止为非常量引用产生临时对象。同时证明引用类型传参不会产生临时变量,如char[]转换成string会报错,他们都是引用类型。

        临时变量不能作为非const引用参数,不是因为他是常量,而是因为c++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制,意在限制这个非常规用法的潜在错误。



C++中的临时变量

C++的临时变量 它们是被神所遗弃的孩子,没有人见过它们,更没有人知道它们的名字.它们命中注定徘徊于命运边缘高耸的悬崖和幽深的深渊之间,用自己短暂的生命抚平了生与死之间的缝隙.譬如朝露,却与阳光无缘....
  • wangjiwei2010
  • wangjiwei2010
  • 2007-05-25 15:34:00
  • 4472

C++临时变量的产生

产生临时变量的三种情况:一:以By Value的方式传值;二:参数为const的类型。三:类型转换 一:以By Value的方式传值。      我们都知道,引用类型和指针类型传递的都是地址,可以直接...
  • qq_38193597
  • qq_38193597
  • 2017-04-16 09:30:46
  • 824

C/C++中的临时变量

说到临时变量,我们大家也许都挺熟悉, 但是我自己对临时变量的理解却一直存在一个误区。通常情况下,我会把为了做某一件事情而临时创建的一个变量叫做临时变量。比如说在交换两个变量的值时,通常我们会创建第三个...
  • Joey_ZengChen
  • Joey_ZengChen
  • 2007-04-16 16:29:00
  • 2958

C++讨厌的临时变量什么时候产生

作者:陈太汉 是的。我们讨厌产生临时变量,因为它要占用我们的内存,消耗我们的CPU时间,让我们的程序性能降低。但有时候它是必须的。 那讨厌的临时变量什么时候产生呢?产生临时变量的三种情况:一:以By ...
  • chentaihan
  • chentaihan
  • 2011-07-06 11:50:35
  • 912

[C++]引用参数与临时变量

对于引用参数,什么情况下会产生临时变量了?C++为什么对于产生临时变量的引用参数要加const?...
  • Jamienstar
  • Jamienstar
  • 2016-12-27 18:22:01
  • 1041

C++临时变量什么时候销毁

https://www.zhihu.com/question/23511471 和上面的问题差不多。 http://www.cnblogs.com/xkfz007/articles/2506022.h...
  • a627088424
  • a627088424
  • 2015-12-20 22:04:07
  • 1296

C++值传递时返回临时变量,引用传参

在C++中,引用不会产生新变量,所以在引用做返回值的时候,就不会产生临时变量,上代码:int a = 10; int fun() { int b = 10,c = 12; a = b ...
  • lixungogogo
  • lixungogogo
  • 2016-03-27 10:19:15
  • 887

C++中返回临时变量指针问题

如下面所示的这个程序,按照道理 cChar应该是局部变量,在函数调用结束时,就应该销毁了,为什么还能返回呢? 这是因为,在函数结束的时候,销毁的只是局部变量,但是该局部变量指向的这个内存单元仍然存在,...
  • Chuekup
  • Chuekup
  • 2012-05-17 17:05:06
  • 1806

[c/c++]临时变量、局部变量,return的效率

如果函数返回值是一个对象,要考虑 return 语句的效率。例如          return String(s1 + s2); 这是临时对象的语法,表示“创建一个临时对象并返回它” 。不要以为它与...
  • believefym
  • believefym
  • 2007-10-29 13:56:00
  • 3445

什么时候c++会生成临时变量(2014年9月3日13:47:24)

如果实参与引用参数不匹配,C++将生产临时变量。 如果引用参数是const,,则编译器将在下面两种情况下生成临时变量: 1. 实参的类型正确,但不是左值。 例如: double ref(con...
  • xuchiyu
  • xuchiyu
  • 2014-09-03 14:24:03
  • 535
收藏助手
不良信息举报
您举报文章:c++中的临时变量
举报原因:
原因补充:

(最多只允许输入30个字)