說到構造函數,通常是將講對象創建時編譯器自動調用構造函數為對象初始化,也可以說是分配內存空間。
學習了構造函數 相對其中牽涉到的一些點作下大概的了解和學習,整理一下只是點。
這里主要說下 類與結構體的差異/類與結構體包含繼承關系時的構造調用/類的初始化列表/默認構造函數/拷貝構造函數以及牽涉到的相關內容
結構體和類的區別
對於結構中的實例字段成員,不能在聲明時賦值初始化
聲明了結構類型后,可以使用new運算符創建構造對象,也可以不用new。若不用new,那在初始化所有字段之前,字段將保持未賦值狀態且對象不可用
結構在堆棧中創建,是值類型,而類是引用類型
值類型和引用類型的區別
byte,short,int,long,float,double,decimal,char,bool 和 struct 統稱為值類型。值類型變量聲明后,不管是否已經賦值,編譯器為其分配內存
string 和 class統稱為引用類型。當聲明一個類時,只在棧中分配一小片內存用於容納一個地址,而此時並沒有為其分配堆上的內存空間。當使用 new 創建一個類的實例時,分配堆上的空間,並把堆上空間的地址保存到棧上分配的小片空間中
注:new 的位置可以堆可以棧?如何查看具體的位置呢? --- linux
最后一項是映射的文件名。對匿名映射來說,是此段虛擬內存在進程中的角色。[stack]表示在進程中作為棧使用,[heap]表示堆。其余情況則無顯示
第一個示例可以確認的是new的數據此時並不在堆數據區中/ then……實際上應該在哪呢?——待確認【==|`】
結構體與類的構造函數--包含&繼承 關系下是否會有差異呢?
他們之間的調用初始化關系: 初始化會分配空間和賦隨機值
示例:-(S=Struct C=Class Con=Conntain Inher=Inherit)
結論:不論包含還是繼承 都會調用 相關的構造函數,不用多次給成員初始化處理
此處需要使用單步調試確認順序 (VS2017 使用F10調試)
-
包含關系中,按照成員聲明的順序進行構造初始化,而不是按照初始化列表的順序初始化
-
-
繼承關系中,先調用父類的構造 ,再按照聲明的順序
初始化列表 & 默認構造函數 & 靜態構造函數 & 拷貝構造函數
需使用初始化列表的條件:
數據成員是對象,並且這個對象只有含參數的構造函數,沒有無參數的構造函數
對象引用或者cosnt修飾的數據成員
子類初始化父類的私有成員,需要在(並且也只能在)參數初始化列表中顯示調用父類的構造函數
默認構造函數:csdn什么是默認構造函數
-
沒有帶明顯形參的構造函數。
-
提供了默認實參的構造函數。
warning: 編譯器自動合成默認構造函數的誤區
合成默認構造函數總是不會初始化類的內置類型及復合類型的數據成員。(如 int / bool ……)
分清楚默認構造函數被程序需要與被編譯器需要,只有被編譯器需要的默認構造函數,編譯器才會合成它
編譯器需要去合成默認構造的條件:
含有類對象數據成員,該類對象類型有默認構造函數
基類帶有默認構造函數的派生類
帶有虛函數的類
帶有虛基類的類
靜態構造函數
1.靜態構造函數既沒有訪問修飾符,也沒有參數
2.在創建第一個實例或引用任何靜態成員之前,將自動調用靜態構造函數來初始化類
3.無法直接調用靜態構造函數
4.在程序中,用戶無法控制何時執行靜態構造函數
拷貝構造函數詳解
一種特殊的構造函數,函數的名稱必須和類名稱一致,它必須的一個參數是本類型的一個引用變量。
作用就是用來復制對象的,在使用這個對象的實例來初始化這個對象的一個新的實例