C++的對象在記憶體中是怎麼表示的,資料成員和成員函數之間有什麼關係,this指標到底是幹嘛的。
這裡不考慮虛函數表
一個對象記憶體中占的大小其實就是他的資料成員的大小
這是我用的例子
class T{public: T() {} void info() const { cout << "info\n"; } void printValue() const { cout << "value is " << m_value << '\n'; } void fun() const { cout << "fun!\n"; }private: int m_value;};
注釋掉fun函數和沒注釋的大小都是一個int的大小,4byte。
那麼成員函數類是共用一份代碼,但是我們在使用的時候,為什麼感覺是每個對象都自己有一份,這和兩個方面有原因。我們在施加一個動作給一個對象時,這個對象的狀態只能由它的資料成員能夠記錄和表示,我們在需要施加操作的對象身上由它的對象的資料成員所代表的狀態是我們預期的結果,是我們感覺是各自一份。還有就是this指標是造成假象的技術實現。
int main(){ T *p = NULL; p->info();// p->printValue();// t *p2 = NULL;// info(p2); // cout << sizeof(T) << endl; return 0;}
我們在main函數中寫了這段代碼,你認為只是不可接受的,確實是,你不能對一個NULL執政施加操作,可是結果是
這樣的
它很好的運行了。
現在我們寫了這一段代碼
struct t { int m_value;};void info(const t *p) { cout << "info\n";}void printValue(const t *p) { cout << "value is " << p->m_value << '\n';}
在main函數中寫了這段
int main(){// T *p = NULL;// p->info();// p->printValue(); t *p2 = NULL; info(p2);// cout << sizeof(T) << endl; return 0;}
其實這兩個已經可是瞭解C++對象的原型了,p2就是this指標,它是NULL,不過我們在info中沒有使用它,所以它沒什麼影響,這就是第一段代碼能夠啟動並執行原因,可是如果我們call了printValue函數,this是NULL,我們在函數中訪問了它的m_value,我們省略了this->,這就和
void printValue(const t *p)
一樣
一個記憶體段錯誤。