C++中的臨時變量指的是那些由編譯器根據需要在棧上產生的,沒有名字的變量。
主要的用途主要有兩類:
1) 函數的返回值, 如:
1 string proc()
2
3 {
4
5 return string("abc");
6
7 }
8
9
10
11 int main()
12
13 {
14
15 proc();
16 return 0;
17
18 }其中第15行會產生一個臨時變量。但並不是所有返回值都會創建臨時變量,只有當沒有將返回值賦值給其它變量時,臨時變量才會創建。
這種臨時變量的生命周期很短,當表達式完成後,它就會被銷毀了。例如上面的代碼,15行產生的臨時變量,16行的時候就已經銷毀了。
2) 類型轉換時的中間變量。
1 int a = 3;
2
3 float k = 2.0;
4 float f = k + a;第4行,k+a由於是float + int , int 會被轉換成float再與k相加,這個時候就會生產一個臨時變量。
上面的例子是build-in type,但對於自定義的類也是同樣適用的。
一般來說,C++中的臨時變量在表達式結束之後就被會銷毀,比如前面舉的兩個栗子,但也有例外的時候,如果這個臨時變量被用來初始化一個引用的話,那這個臨時變量的生命周期就會被延長,直到引用被銷毀,從而不會因此產生懸空(dangling)的引用。
1 string Proc()
2 {
3 return string("abc");
4 }
5
6 int main()
7 {
8 const string& ref = Proc();
9 cout << ref << endl;
10 return 0;
11 }如上,第8行產生的臨時變量因為有ref指向,它的生命周期會延長至直到main()返回。
這個特性有時很有用,比如,你可以用一個基類的引用指向一個子類的臨時變量,然後通過這個引用來實現多態,但又不用處理子類的銷毀。
1 Class Base()
2 {
3 public:
4
5 virtual Bar() { cout << "base bar()" << endl; }
6 };
7
8 Class DerOne: public Base
9 {
10 public:
11
12 virtual Bar() { cout << "DerOne Bar()" << endl; }
13 };
14
15 class DerTwo: public Base
16 {
17 public:
18
19 virtual Bar() { cout << "DerTwo Bar()" << endl; }
20 };
21
22
23 Base GetBase()
24 {
25 return Base();
26 }
27
28 DerOne GetDerOne()
29 {
30 return DerOne();
31 }
32
33 DerTwo GetDerTwo()
34 {
35 return DerTwo();
36 }
37
38
39 int main()
40 {
41 Base& ref1 = GetBase();
42 Base& ref2 = GetDerOne();
43 Base& ref3 = GetDerTwo();
44
45 ref1.Bar();
46 ref2.Bar();
47 ref3.Bar();
48
49 return 0;
50 }這個小技巧在Loki::ScopeGuard的實現中就用到了,使得在一個域內使用多態時,不用通過指針。
不過需要注意的是,臨時變量只能用const 引用來指向,因此是不可修改的。