1. 程式人生 > >C++筆記 第五十課 C++物件模型分析(上)---狄泰學院

C++筆記 第五十課 C++物件模型分析(上)---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習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++中的類物件在記憶體佈局上與結構體相同
成員變數和成員函式在記憶體中分開存放
訪問許可權關鍵字在執行時失效
呼叫成員函式時物件地址作為引數隱式傳遞