C++臨時變量的生命周期


C++ 中的臨時變量指的是那些由編譯器根據需要在棧上產生的,沒有名字的變量。主要的用途主要有兩類:

1) 函數的返回值, 如:

 1 string proc() 
 2 {
 3     return string("abc");
 4  }
 5  
 6 int main()
 7 {
 8     proc();
 9     return 0; 
10 }

其中第 8 行會產生一個臨時變量。但並不是所有返回值都會創建臨時變量,只有當沒有將返回值賦值給其它變量時,臨時變量才會創建。這種臨時變量的生命周期很短,當表達式完成后,它就會被銷毀了。例如上面的代碼,第 8 行產生的臨時變量,到第 9 行的時候就已經銷毀了。

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++ 中的臨時變量在表達式結束之后 (full expression) 就被會銷毀,比如前面舉的兩個栗子,但也有例外的時候,如果這個臨時變量被用來初始化一個引用的話,那這個臨時變量的生命周期就會被延長,直到引用被銷毀,從而不會因此產生懸空(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     const Base& ref1 = GetBase();
42     const Base& ref2 = GetDerOne();
43     const Base& ref3 = GetDerTwo();
44 
45     ref1.Bar();
46     ref2.Bar();
47     ref3.Bar();
48   
49     return 0;
50 }

該小技巧在 Loki::ScopeGuard 的實現中被用到了,使得在一個域內使用多態時,可以避免使用指針,這個寫法是這樣的巧妙以致被 Andrei 稱為:"The Most Important const"。不過需要注意的是,臨時變量只能通過 const 引用來指向,因此是不可修改的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM