C++筆記 第五十課 C++物件模型分析(上)---狄泰學院
阿新 • • 發佈:2018-12-01
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第五十課 C++物件模型分析(上)
1.迴歸本質
class是一種特殊的struct
在記憶體中class依舊可以看做變數的集合
class與struct遵循相同的記憶體對齊規則
class中的成員函式與成員變數是分開存放的
每個物件由獨立的成員變數
所有物件共享類中的成員函式
值得思考的問題
50-1 物件記憶體佈局初探
#include <iostream> #include <string> using namespace std; class A { int i; int j; char c; double d; public: void print() { cout << "i = " << i << "," << "j = " << j << "," << "c = " << c << "," << "d = " << d << endl; } }; struct B { int i; int j; char c; double d; }; int main() { A a; cout << "sizeof(A) = " << sizeof(A) << endl;//4+4+4+8 20bytes cout << "sizeof(a) = " << sizeof(a) << endl; cout << "sizeof(B) = " << sizeof(B) << endl;//4+4+4+8 20bytes a.print(); B* p = reinterpret_cast<B*>(&a); p->i = 100; p->j = 200; p->c = 'C'; p->d = 3.14; a.print(); return 0; } 執行結果 sizeof(A) = 24 sizeof(a) = 24 sizeof(B) = 24 i = 4197456,j = 0,c = ,d = 6.95323e-310 i = 100,j = 200,c = C,d = 3.14
2.C++物件模型分析
執行時的物件退化為結構體的形式
所有成員變數在記憶體中依次排布
成員變數間可能存在記憶體空隙
可以通過記憶體地址直接訪問成員變數
訪問許可權關鍵字在執行時失效
類中的成員函式位於程式碼段中
呼叫成員函式時物件地址作為引數隱式傳遞
成員函式通過物件地址訪問成員變數
C++語法規則隱藏了物件地址的傳遞過程
50-2 物件本質分析
面向物件不是C++專有的,依然可以用C語言來寫
C語言中,對於一個類而言,成員函式和成員變數在記憶體裡面是分開存放的,這一點非常重要,如果掌握了這些本質,就可以編寫任何面向物件的程式碼
C++程式:50-2.cpp
#include <iostream> #include <string> using namespace std; class Demo { int mi; int mj; public: Demo(int i, int j) { mi = i; mj = j; } int getI() { return mi; } int getJ() { return mj; } int add(int value) { return mi + mj + value; } }; int main() { Demo d(1, 2); cout << "sizeof(d) = " << sizeof(d) << endl; //8 bytes cout << "d.getI() = " << d.getI() << endl; //1 cout << "d.getJ() = " << d.getJ() << endl; //2 cout << "d.add(3) = " << d.add(3) << endl; //6 return 0; }
C語言中的程式:50-2.h ,50-2.c, main.c
50-2.h
#ifndef _50_2_H_
#define _50_2_H_
typedef void Demo;
Demo* Demo_Create(int i, int j);
int Demo_GetI(Demo* pThis);
int Demo_GetJ(Demo* pThis);
int Demo_Add(Demo* pThis, int value);
void Demo_Free(Demo* pThis);
#endif
50-2.c #include "50-2.h" #include "malloc.h" struct ClassDemo { int mi; int mj; }; Demo* Demo_Create(int i, int j) { struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo)); if (ret != NULL) { ret->mi = i; ret->mj = j; } return ret; } int Demo_GetI(Demo* pThis) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mi; } int Demo_GetJ(Demo* pThis) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mj; } int Demo_Add(Demo* pThis, int value) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mi + obj->mj +value; } void Demo_Free(Demo* pThis) { free(pThis); }
Main.c
#include "50-2.h"
#include "malloc.h"
struct ClassDemo
{
int mi;
int mj;
};
Demo* Demo_Create(int i, int j)
{
struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo));
if (ret != NULL)
{
ret->mi = i;
ret->mj = j;
}
return ret;
}
int Demo_GetI(Demo* pThis)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mi;
}
int Demo_GetJ(Demo* pThis)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mj;
}
int Demo_Add(Demo* pThis, int value)
{
struct ClassDemo* obj = (struct ClassDemo*)pThis;
return obj->mi + obj->mj +value;
}
void Demo_Free(Demo* pThis)
{
free(pThis);
}
執行結果
d.mi = 1
d.mj = 2
Add(3) = 6
小結
C++中的類物件在記憶體佈局上與結構體相同
成員變數和成員函式在記憶體中分開存放
訪問許可權關鍵字在執行時失效
呼叫成員函式時物件地址作為引數隱式傳遞