第十章深入函式
學習一些函式的高階特性,比如函式的過載等。
10.1函式的過載
我們可以將相同名字、但是不同型別的函式重複呼叫多次,來處理不同型別的資料。這裡可以具體分為普通函式的過載和成員函式的過載。
10.2函式的預設引數
在定義函式的時候,可以將它初始化乙個值,這個值就叫函式的預設引數,也叫預設引數。這樣函式在呼叫的時候,如果有傳遞引數就用現成的,如果沒有就用的這個預設引數。
這裡要和過載函式做乙個區分。
過載函式容易理解;但是對於預設引數,如果不加注釋,很容易被忽略,而且很容易被有引數的同名函式覆蓋。
過載函式過載的是引數型別,而預設引數過載的是引數的值。
10.3建構函式的過載
函式都可以被過載,建構函式當然也具備這個特性。
10.3.1成員變數的初始化
對成員變數的初始化有很多方式。
一是在建構函式體中進行初始化。這要與過載建構函式配合使用。
二是就在建構函式的函式頭進行初始化。具體操作就是在建構函式右邊加冒號(:),然後是成員變數的名稱和小括號(),小括號裡面寫入初始化的值或表示式。多個初始化成員用逗號隔開。
注意:由於常量和引用只能被初始化,不能被賦值,所以最好在建構函式的函式頭中對常量和引用進行初始化。
10.3.2成員變數的初始化與建構函式
當乙個物件包容多個另一類物件的時候,被包容進去的子物件,在執行建構函式的時候,是按照成員列表的順序進行構造的,而不是按照初始化順序構造的。
析構順序恰巧與構造順序相反,最後構造的最先析構,也就是棧的後進先出原則。
最後再強調一下建構函式初始化的用途:如果成員是常量和引用,那麼只能在建構函式頭進行初始化。
10.3.3複製建構函式
複製建構函式可以複製乙個物件。
複製建構函式的函式名:與建構函式一樣,都是完全和類名相同。
函式引數:該類的引用,比如 a(a&one)。這就是類a物件的乙個複製建構函式。
預設複製建構函式的執行機理:由於它有指向類a的乙個引用(引用名為one),因此就可以通過這個引用來訪問類a的乙個物件,從而複製該物件的成員變數。
這個工作由編譯器自動完成。如果成員是指標,就涉及到深層或淺層複製的問題,後面會詳細介紹,就需要我們人為干預了。
複製建構函式的用途:可以用來初始化另乙個物件,把我們想要的那個物件的成員直接複製過來。
10.3.4建構函式和new運算子
通過前面對棧的學習可知,系統會自動在棧中為每個變數開闢記憶體空間,以保證數值合理的被釋放。
棧有優點,速度快,但是也有缺點,就是可存放的空間比較小,只有2m。
所以我們要用堆。堆是一大堆不連續的記憶體區域,在系統中由鍊錶將其串接起來。所以它空間很大。
堆和棧的兩點不同:
棧由系統自動分配,堆要由程式設計師申請。
棧空間小,只有2m。堆的上限由系統中有效的虛擬記憶體來決定,因此可獲得的空間較大。
指標申請空間
指標 -> 操作
釋放空間
10.3.5再談預設建構函式
只要自己建立了乙個建構函式,編譯器便不再自動為我們建立。如果還想要編譯器提供的那種原生的建構函式,就必須自己再建立乙個。
10.4析構函式和delete運算子
delete運算子會自動呼叫析構函式,來釋放掉new運算子所申請的記憶體空間。
預設析構函式:原理與用法和建構函式相同。
呼叫建構函式進行型別轉換。盡量不用吧,沒看到有多大好處,用explicit關鍵字對建構函式進行限定,就可以禁止這種轉換。
10.5淺層複製建構函式
預設複製建構函式+指標成員變數+堆空間。
如果析構掉乙個,另乙個再用的時候就會崩潰。原因也很簡單,二者都指向同一塊堆空間,在析構乙個的時候,堆空間被釋放掉了,另乙個就變成了迷途指標,再呼叫就會崩潰。
預設複製建構函式的這種拷貝方式叫做成員拷貝,也叫淺拷貝。比較容易出現上述問題。
10.6深層複製建構函式
為解決這個問題,我們必須建立自己的複製建構函式,並且在函式裡為成員變數分配記憶體。兩個物件的成員變數各自擁有自己的記憶體,就不會影響到對方。這種方式就是深層複製。
C 學習筆記( )
一 語法 迴圈 foreach 型別識別符號 in 表示式 code 用法 例子int temp foreach int num in temp 每次從temp取乙個元素賦給num直至取完 console.writeline n num 每行顯示乙個元素 執行結果 c 中唯讀 只寫控制 class ...
C 學習筆記
1.函式特徵 有函式頭和函式體 接受乙個引數 返回乙個值 需要乙個原型。2.c 命名規則 在名稱中只能使用字母字元 數字和下劃線 名稱的第乙個字元不能是數字 區分大寫字母和小寫字母 不能將c 關鍵字用作名稱 以兩個下劃線或下劃線和大寫字母打頭的名稱被保留給實現 編譯器及其使用的資源 使用,以乙個下劃...
c 學習筆記
屬性 屬性開頭字母大寫 屬性可以判斷輸入的非法值 屬性本身不儲存值 依靠字段 索引器 using system using system.collections.generic using system.linq using system.text namespace b try catch exc...