1、2022/8/5生存空間和生命週期以及多載化函式1生存空間和生命週期以及多載化函式C+Primer 第三版中文版Chap 8.18.4Chap 92022/8/5生存空間和生命週期以及多載化函式2C+中有關宣告(declarations)的問題n宣告動作所導入的符號名稱可以在何處使用?n提示:C+scope(生存空間)包括 global scope,local scope,namespace scope.n程式何時可以安全使用object或函式?n提示:object的生命週期nglobal:能夠維持生命到整個程式結束為止.nlocal:只能在程式的部分期間維持生命.n動態配置:期生命由程式員控
2、制.2022/8/5生存空間和生命週期以及多載化函式3Local Scope(區域性生存空間)n所謂local scope是程式本文的部分範圍.n位於一個函式區塊之內.n每個函式都表現有各自的local scope.n函式中每一個複合敘述句(或說區塊,block)也表現有它自己的一個local scope.nlocal block scopes可以巢狀出現.2022/8/5生存空間和生命週期以及多載化函式4Local Scope範例int binarySearch(int val,)/binarySearchs scope startint a;/scope包含binarySearch,whi
3、le,if.while()/while loop scope startint b;/scope 包含 while,if.if()/if statement scope startint c;/scope 包含 if./if statement scope end/while loop scope end/binarySearchs scope end2022/8/5生存空間和生命週期以及多載化函式5全域物件(Global Objects)&全域函式(Global Functions)n函式如果宣告在於global scope中,便是一個全域函式.n變數如果宣告在於global scope中,
4、便是一個全域物件.n全域物件是整個程式執行期間都存在的一個物體,生命期從程式啟動開始,直到程式結束.n全域物件和non-inline全域函式在程式中都只能定義一次.2022/8/5生存空間和生命週期以及多載化函式6extern宣告式n讓多個.cpp檔案組成的程式能使用同一個object.n寫法:extern 資料型別 物件名稱;n使用extern並不會再額外配置記憶體.n可放置於表頭檔中.n範例程式:ExternDemo.cpp2022/8/5生存空間和生命週期以及多載化函式7Local Objects(區域性物件)nAutomatic Objects(自動配置與釋放的襪件)nRegister
5、 Automatic Objects(放在暫存器裡的物件)nStatic Local Objects(靜態的區域性物件)n此三類皆位於Local Scope.2022/8/5生存空間和生命週期以及多載化函式8Automatic Objects-1n生命週期從宣告之後一直到scope結束.n例如:void main()int a;int b;b的生命週期a的生命週期2022/8/5生存空間和生命週期以及多載化函式9Automatic Objects-2n承上頁,所以“”可以看做內含釋放所有非由 new 關鍵字建立的object的記憶體的程式碼.n以下是危險的做法:int*trouble()int
6、 res;.return&res;/危險的,因為res的記憶體已經被釋放了.2022/8/5生存空間和生命週期以及多載化函式10Register Automatic Objectsn對於的automatic objects,可以用關鍵字register修飾他們.n常見的候選者為迴圈中的counterfor(register int i=0;i10000;i+)nregister是對編譯器的一種.n此種object會使用機器暫存器(CPU)來儲存資料,如果不能夠,就使用記憶體儲存.2022/8/5生存空間和生命週期以及多載化函式11Static Local Objects n生命週期同globa
7、l object(整個程式期間)nobject可見度受限於local scope.n初值初始化動作僅做第一次.n範例程式:LocalObjectDemo.cppn如果宣告時沒有給定初值,則內定初值為0.n驗證程式:LocalObjectInit.cpp2022/8/5生存空間和生命週期以及多載化函式12動態配置的物件n使用指標和 new,delete 算式.n程式不會自動釋放利用new配置的記憶體,程式設計師必須自行用delete釋放.n如果 delete 的運算元為0(NULL)的話,就不會執行釋放記憶體的動作.n所以在指標所指的object被刪除之後,把指標設為0是一個好習慣.n驗證程式:
8、DeleteNullDemo.cpp2022/8/5生存空間和生命週期以及多載化函式13動態記憶體有關的常見錯誤n沒有實施delete算式,造成記憶體沒有歸還給自由空間,亦即所謂的記憶體漏洞(memory leak).n對同一個記憶體位址實施delete算式兩次,通常發生在“兩個指標指向同一塊動態配置之object”的情況下.nobject被刪除之後又對它做讀寫動作.2022/8/5生存空間和生命週期以及多載化函式14多載化函式(Overloaded Functions)n以下是多載化(Overloaded)之定義:n多個函式名稱相同.n宣告於相同scope中.n各自擁有不同的參數列.n例如:
9、int max(int,int);int max(int,int);int max(char*,int);2022/8/5生存空間和生命週期以及多載化函式15編譯器對同名函式的解讀-1n在之後的四頁皆是同一個scope.n如果兩個函式的參數列不同(不論是參數個數不同或其型別不同),這兩個函式便被視為多載化.n例如:/overloaded functionvoid print(char*);void print(string&);2022/8/5生存空間和生命週期以及多載化函式16編譯器對同名函式的解讀-2n如果兩個函式宣告的傳回值型別和參數列都完全相同,那麼第二個函式會被視為第一個函式的重複宣
10、告.n例如:/宣告相同的函式void print(char*str);void print(char*);2022/8/5生存空間和生命週期以及多載化函式17編譯器對同名函式的解讀-3n如果兩個函式的參數列完全相同,但是傳回值型別不同,那麼第二個函式會被視為第一個函式的錯誤性重複宣告,並在編譯時期被標示出來.n單單“函式的傳回值型別”,不足以區分兩個多載化函式.n例如:unsigned int max(int,int);int max(int,int);/error.2022/8/5生存空間和生命週期以及多載化函式18編譯器對同名函式的解讀-4n如果兩個函式的參數列只有預設引數不同,那麼第二個
11、函式會被視為第一個函式的重複宣告.n例如:/宣告相同的函式int max(int*,int);int max(int*,int=10);n範例程式:OverLoadDemo.cpp2022/8/5生存空間和生命週期以及多載化函式19typedef所造成的型別問題ntypedef可以為即有的資料型別,提供另一個型別名稱,但並非產生新的型別.n所以下列是相同的重複宣告:typedef double DOLLAR;DOLLAR calc(DOLLAR);double calc(double);n驗證程式:TypedefOLDemo.cpp2022/8/5生存空間和生命週期以及多載化函式20什麼時候不
12、需要將函式多載化?n如果不同的函式名稱所帶來的訊息可以讓程式更容易被人了解,那麼就不需要為函式做多載化.n通常多載化函式,用在一群有相同動作的函式.2022/8/5生存空間和生命週期以及多載化函式21多載決議程序的三個步驟n步驟一:確認此一函式呼叫動作所對應的多載函式集合,並確認函式呼叫動作中的引數列性質.n步驟二:從多載函式集中挑選出可被呼叫的函式.n步驟三:選擇與呼叫動作最匹配的函式.2022/8/5生存空間和生命週期以及多載化函式22多載決議程序範例-1n範例程式片斷:void f();void f(int);void f(double,double=3.4);void f(char*,
13、char*);void main()f(5.6);n對於f(5.6)來進行多載決議程序.2022/8/5生存空間和生命週期以及多載化函式23多載決議程序範例-2n根據步驟一可找到多載函式的集合:f();f(int);f(double,double);f(char*,char*);n另外並且確定f(5.6)的引數為double型別.2022/8/5生存空間和生命週期以及多載化函式24多載決議程序範例-3n根據步驟二可得下列函式可被呼叫:f(int);/double可轉換成intf(double,double);/第二個參數有設預設引數n如果在此步驟沒有發現可行函式,便會有編譯時期的錯誤,這是一種
14、no match狀態.2022/8/5生存空間和生命週期以及多載化函式25多載決議程序範例-4n根據步驟三從步驟二中選出的函式再挑選一個最佳可行函式(best viable function).n最佳可行函式必須符合以下條件:1.所有引數的轉換行為,不遭於任何其他可行函式所需的轉換行為.2.某些引數身上的轉換行為,優於其他可行函式身上的相同引數所需的轉換行為.2022/8/5生存空間和生命週期以及多載化函式26多載決議程序範例-5n根據最佳可行函式判斷出是f(double,double);n因為不轉換比任何轉換好.n如果無法找出最佳可行函式,則這個函式呼叫動作便告失敗,此為模稜兩可(ambiguous)狀態.2022/8/5生存空間和生命週期以及多載化函式27練習題解答參考n敘述句練習題範例程式:Lesson3HomeWork.cppn函式練習題範例程式:Lesson4HomeWork.cpp