C++知識點總結(面向對象1-類和對象, this指針, 內存佈局)

面向對象1-類和對象

C++中可以使用struct, class來定義一個類
struct 和 class的區別:struct的默認成員權限是public
class的默認的成員權限是private
變量名規範參考:
全局變量: g_ global g_age
成員變量: m_ member m_age
靜態變量: s_
常量: c_ const
或使用駝峯標識 gAge, mAge

面向對象2- 對象的內存

#include <iostream>
using namespace std;

class Person {
public:
    int m_id;
    int m_age;
    int m_height;
    void display() {
        cout << m_id << m_age << m_height << endl;
    }
};

int main()
{
    Person person;
    person.m_id = 1;
    person.m_age = 2;
    person.m_height = 3;
	cout << &person << endl;
	cout << &person.m_id << endl;
	cout << &person.m_age << endl;
	
    return 0;
}

在這裏插入圖片描述

面向對象3-this

函數都存儲在代碼段
局部變量存儲在棧區
那怎麼訪問person1, person2對象的成員變量的?其實內部有this指針, 隱式參數,看不到,在調用函數會把調用者的地址傳過去

面向對象4-指針訪問的本質

原理:如何利用指針間接訪問所指向的對象的成員變量?
1.從指針中取出對象的地址
2.利用對象的地址 + 成員變量的偏移量計算出成員變量的地址
3.根據成員變量的地址訪問成員變量的存儲空間

面向對象5-指針的思考題

面向對象6-0xCC

涉及到函數調用棧
每調用一個函數時, 會給這個函數分配一個棧空間, 但這個棧空間裏面的數據可能是垃圾數據, 也可能是之前別的函數用過的, 所以在真正在用這個棧空間之前,會用CC來填充棧空間, 使這個棧空間裏面的數據全是C,爲什麼用CC來抹掉之前的數據, 不用00呢?
什麼是CC?
如果把CC當做機器碼來看的話, 對應的彙編代碼是int3, int3 : 起到斷點的作用. int3是斷點的意思
在彙編裏面int叫做中斷, 後面的3是中斷碼,中斷碼是3就是斷點的意思
int - interrupt
好處: 假設jmp, jz 後面跟的地址值指錯了, 指成了函數的棧空間,那麼一跳轉到函數的棧空間, 就會執行int3就會停下來, 就不至於假設以前是一些垃圾數據, 可能做一些危險的指令操作.變得安全.這樣的話, 函數的棧空間不小心被別人當做代碼來執行, 那也很安全了.
函數代碼在代碼段, 調用函數, 執行函數代碼其實就是CPU在訪問代碼區的內存(機器指令).
爲什麼函數代碼在代碼區, 又要給函數分配一段棧空間呢?
因爲在函數裏面要定義局部變量, 所以在調用函數時, 要分配一段額外的空間來存放局部變量.
因爲代碼區是隻讀的, 而函數內部的局部變量是可以改的, 所以選擇了棧空間.

內存-封裝, 內存佈局, 堆空間

封裝

成員變量私有化, 提供公共的getter和setter給外界去訪問成員變量.

內存空間的佈局

每個應用都有自己獨立的內存空間, 其內存空間一般都有以下幾大區域:
1.代碼段(代碼區)(Code )
用於存放代碼(機器指令)
2.數據段(全局區)
用於存放全局變量等
3.棧空間
(1)每調用一個函數就會給它分配一段連續的棧空間, 等函數調用完畢後會自動回收這段棧空間.
(2)自動分配和回收
4.堆空間
需要主動去申請和釋放

堆空間

(1)堆空間的價值:
在程序運行過程, 爲了能夠自由控制內存的生命週期, 大小, 會經常使用堆空間的內存.
(2)堆空間的申請\釋放
1.malloc\free
2.new \ delete
int *p = new int;
*p = 10;
delete p;
只要看到new就是向堆空間申請內存
申請什麼看右邊, new int 就是申請一個int類型大小的空間,不用強制類型轉換.
所以直接new int 就是向堆空間申請4個字節, 並且把這4個字節地址值賦值給左邊的指針
char *p = new char;
*p = 10;
delete p;
這個是申請1個字節
3.new [] \ delete[]
char *p = new char[4];
申請了4個連續的字節
delete[] p;

注意:
申請堆空間成功後, 會返回那一段內存空間的地址
申請和釋放必須是1對1的關係, 不然可能會存在內存泄露.

內存-堆空間的初始化

(1)malloc是否初始化與編譯器有關
memset 函數 memory set
int *p = (int * )malloc(sizeof(int)*10);
memset(p, 0, 40);
第一個參數是內存地址
第二個參數是初始化爲什麼值
第三個參數是初始化多少字節
意思是:從p這個地址開始連續的40個字節, 每一個字節都設置爲0
(2)new \ delete
int *p0 = new int; 不會初始化
int *p1 = new int(); 默認初始化爲0
int *p2 = new int(5); 初始化爲傳入的值
int *p3 = new int[3]; 數組元素未被初始化
int *p4 = new int3; 3個數組元素都被初始化爲0
int *p5 = new int[3]{}; 3個數組元素都被初始化爲0
int *p6 = new int[3]{5}; 數組首元素初始化爲5, 其他元素都是0

內存-對象的內存

對象的內存可以存在於3種地方:
全局區(數據段): 全局變量
棧空間:函數裏面的局部變量
堆空間:動態申請內存(malloc, new等)
在這裏插入圖片描述


其他C++系列文章:

C++知識點總結(基礎語法1-函數重載, 默認參數)
C++知識點總結(基礎語法2-內聯函數, const, 引用)
C++知識點總結(面向對象1-類和對象, this指針, 內存佈局)
C++知識點總結(面向對象2-構造函數, 初始化列表)

C++知識點總結(面向對象3-多態)

C++知識點總結(面向對象4-多繼承, 靜態成員static)
C++知識點總結(面向對象5-const成員, 拷貝構造函數)
C++知識點總結(面向對象6-隱式構造, 友元, 內部類, 局部類)
C++知識點總結(其他語法1-運算符重載)
C++知識點總結(其他語法2-模板, 類型轉換, C++11新特性)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章