
1 類的定義① 類是C中一種用戶自定義類型它把數據成員和操作這些數據的成員函數封裝在一起是創建對象的模板。類就是對“數據操作數據的方法”的封裝是創建對象的模板。② 類中的變量稱為類的屬性或成員變量類中的函數稱為類的方法或成員函數。類負責把“數據”和“操作數據黨的方法”封裝到一起訪問限定符負責控制“誰能訪問這些成員”。1.1 類定義格式1.2 訪問限定符C中有三種訪問限定符public、private和protected。①public成員可以被類內部、派生類以及類外部訪問通常用來定義類對外提供的接口。②private成員只能由類自身的成員函數訪問外部和普通派生類不能直接訪問通常用于隱藏類內部實現和保護成員數據。③protected與private類似類外部不能直接訪問但派生類可以訪問因此主要用于繼承。在實際設計種通常把成員變量設為private通過public成員函數對外提供操作接口實現封裝并防止外部隨意破壞對象內部狀態。class定義成員沒有被訪問限定符修飾時默認privatestruct默認public。一個訪問限定符會一直作用到下一個訪問限定符出現為止。C 中的struct通常用于組織數據并經常通過typedef簡化類型名而 C 對struct進行了擴展結構體名本身就是類型名同時struct可以包含成員變量、成員函數以及public/private/protected等訪問限定符因此它和class已經非常接近最主要區別是struct默認public而class默認private。2 實例化2.1 實例化概念類是類型對象是類的一個具體實例是實際存在并占用內存空間的實體。類實例化對象就是根據類這個自定義類型創建一個具體對象的過程。類本身只是對成員變量和成員函數的定義相當于一種類型描述實例化之后得到的對象才是真正在程序運行中存在的實體并會占用內存空間。2.2 對象大小成員函數代碼通常放在程序的代碼區由所有對象共享。對象的大小主要由非靜態成員變量決定而普通成員函數不會增加每個對象的大小。①空類也要占1字節主要是為了保證每個對象在內存中都有唯一、可區分的地址。如果空類對象大小為0那么創建多個空類對象時它們可能占用同一個內存位置就無法保證不同對象擁有不同地址。因此C編譯器通常會給空類對象分配至少1字節的空間這個字節不是用來存成員數據的而是用來標識這個對象在類中確實存在。② 對象大小不包含普通成員函數。成員函數的機器指令只需要保存一份通常放在程序的代碼段中由同一個類的所有對象共享執行而對象本身只需要保存各自獨立的狀態數據也就是非靜態成員變量。對象存在的是“數據”成員函數存放的是“代碼”代碼共享數據獨立所以普通成員函數不計入對象大小。3 this指針this是C普通非靜態成員函數中一個隱含的指針它保存當前調用該成員函數的對象地址。編譯器調用普通成員函數時會隱式地把當前對象的地址傳過去。①this本身是一個常量指針不能讓它重新指向其他對象但可以通過它修改當前對象的數據。誰調用成員函數this就指向誰成員函數通過this找到當前對象的數據。②this不是對象的成員變量不占對象空間并且靜態成員函數中不存在this指針。③this指針本質上是成員函數的一個隱含參數所以它并不是固定存放在某“內存區域”中的成員變量。在現代C的實際調用約定下this往往優先通過CPU寄存器傳遞如果寄存器不夠或編譯器需要保存它也可能臨時放到當前函數的棧幀中。之所以這樣是因為this只在成員函數調用期間有意義用來告訴函數“當前操作的是哪個對象”它不屬于對象本身因此不會存在對象所在的堆區或棧區中也不會加入sizeof(對象)。this不是像對象/變量那樣“分配在某個內存區域”的實體而是成員函數被調用時由編譯器隱式傳入的當前對象指針值通常走寄存器/棧傳參實現調用期存在它指向當前對象本身所在的位置。① 通過對象指針調用成員函數時指針會作為當前對象的地址傳給隱藏的this指針。②如果對象指針是nullptr就不存在一個有效的當前對象。此時通過它調用非靜態成員函數屬于未定義行為一旦訪問this-_a這樣的成員通常就會因為非法訪問內存而崩潰。③通過空指針調用非靜態成員函數本身就屬于未定義行為不能認為“只要函數里不訪問成員變量就一定安全”。