標籤:複製 內容 釋放 定義 完成 名稱 pop object 局部對象
1.當我們調用一個函數時,會在記憶體中建立起一塊特殊地區,稱為“程式棧”,這塊特殊地區提供了每個函數參數的儲存空間,它也提供函數所定義的每個對象的記憶體空間--我們將這些對象稱為局部對象。一旦函數完成,這塊記憶體就會被釋放掉,或者是說從程式堆棧中被pop出來。
2.Pass by Reference語意
reference扮演著外界與對象之間的一個間接號碼牌的角色,只要在型別名稱和reference名稱之間插入&符號,便是聲明了一個reference:
1 int ival=1024; //對象,型別為int2 int *pi=&ival; //pointer(指標),指向一個int對象3 int &rval=ival; //reference(化身),代表一個int對象
當我們這麼寫:
1 int jval=4096;2 rval=jval;
時,便是將jval賦值給rval所代表的對象(也就是ival).我們無法rval改為代表jval,因為C++不允許我們改變reference所代表的的對象,它們必須從一而終,當我們寫:
1 pi=&rval;
時,我們其實是將ival(此為rval所代表的之對象)的地址賦值給pi.我們並未令pi指向rval.注意,重點是面對reference的所有操作都像面對“reference 所代表之對象”所進行的操作一般無二。當我們以reference作為函數參數時,亦複如此。
當swap()函數將val2賦值給val1:
1 void swap()2 {3 //實際參數的值會因而改變4 int temp=val1;5 val1=val2;6 val2=temp;7 }
時,的確是將vec[jx]賦值給vec[ix]--前者是val2所代表的之物,後者是val1所代表的之物:
1 swap(vec[ix],vec[jx]);
當我們以by reference 方式傳遞對象當做函數參數,對象本身並不會複製出另一份——複製的是對象的地址。函數中對該對象進行的任何操作,都相當於是對傳入的對象進行間接操作。
將參數聲明為reference的理由之一是,希望得以直接對所傳入的對象進行修改。這個理由極為重要,因為就像我們在前面的例子中所見,不這麼做的話,程式無法正確運行。
將參數聲明為reference的第二個理由是,為了降低複製大型物件的負擔。這個理由相較起來不那麼重要,因為對程式而言不過是效率議題罷了。
3.舉個例子,現在我將打算顯示的vector以傳值方式傳入display()中,這意味著每當我想進行顯示操作時,vector內的所有元素都會被複製。這並不會造成錯誤,但是如果直接傳入vector地址,速度會更快。將vector的參數聲明為reference,便可達到這個目的。
1 void display(const vector<int> &vec)2 {3 for(int ix=0;ix<vec.size();++ix)4 {5 cout<<vec[ix]<<" ";6 cout<<endl;7 }8 }
我們聲明了一個 reference to const vector ,因為函數之中並不會更改vector的內容,少了const並不會造成錯誤,但加上const可以讓閱讀程式的人瞭解,我們以傳址的方式來傳遞vector,為的是避免重複操作,而不是為了要在函數之中對它進行修改。
如果我們願意,也可以將vector以pointer的形式傳遞。這和以reference傳遞的效用相同:傳遞的是對象的地址,而不是整個對象的複製品。唯一的差別在於reference和pointer的用法不同,例如:
1 void display(const vector <int> *vec) 2 { 3 if(!vec) 4 { 5 cout<<"display():the vector pointer is 0\n"; 6 return ; 7 } 8 9 for(int ix=0;ix<vec->size();++ix)10 {11 cout<<(*vec)(ix)<<" ";12 cout<<endl;13 }
1 int main()2 {3 int ia[8]={1,2,1,12,2,2,1,1};4 vector<int> vec(ia,ia+8);5 6 cout<<"vector before sort";7 display(&vec);//傳入地址8 // 其餘代碼9 }
pointer參數和reference 參數二者之間更重要的差異是,pointer可能(也可能不)指向某個實際對象,當我們提領pointer時,一定要先確定其值並非0.至於reference則必定會代表某個對象,所以不需要做此檢查。
一般來說,除非你希望在函數內更改參數值,否則在傳遞內建型別時,不要使用傳址方式,傳址方式主要是作為傳遞class object 之用。
Essential C++學習筆記