日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【C++深度剖析教程28】C++对象模型分析

發(fā)布時(shí)間:2023/12/10 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++深度剖析教程28】C++对象模型分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

學(xué)習(xí)交流加

  • 個(gè)人qq:
    1126137994
  • 個(gè)人微信:
    liu1126137994
  • 學(xué)習(xí)交流資源分享qq群:
    962535112

今天記錄學(xué)習(xí)的內(nèi)容是:C++對(duì)象模型分析!!!

本質(zhì)分析:
class是一種特殊的struct

  • 在內(nèi)存中class依舊可以看做是變量的集合
  • class與struct遵循相通的對(duì)齊準(zhǔn)則
  • class中的成員函數(shù)與成員變量是分開(kāi)存放的
    *每個(gè)對(duì)象有獨(dú)立的成員變量
    *所有對(duì)象共享類中的成員函數(shù)
    下圖中的結(jié)果是什么?

上面的結(jié)果需要分情況討論,但是不管結(jié)果是多少,它們兩個(gè)都是相等的,因?yàn)閏lass本身就是一種特殊的struct。
下面來(lái)總結(jié)一下,結(jié)構(gòu)體的字節(jié)對(duì)齊,以及它在不同編譯器中的不同的對(duì)齊方式!

Linux系統(tǒng)下:GCC默認(rèn)為4字節(jié)對(duì)齊,有多個(gè)低字節(jié)類型的變量(這多個(gè)低字節(jié)類型(低于字節(jié)對(duì)齊的大小)的變量是連續(xù)存儲(chǔ)的,中間沒(méi)有其他高于4字節(jié)類型變量),則這多個(gè)低字節(jié)類型的變量組成后的字節(jié)總數(shù),再與4字節(jié)對(duì)齊(即4的倍數(shù))
windows下的VS編譯器:以最高字節(jié)類型的字節(jié)數(shù)對(duì)齊,同理有多個(gè)低字節(jié)類型的變量的話(這多個(gè)低字節(jié)類型的變量(低于對(duì)齊字節(jié)的大小)是連續(xù)存儲(chǔ)的,中間沒(méi)有其他類型變量),加在一起再與最大類型字節(jié)數(shù)做對(duì)比(即最大字節(jié)數(shù)的倍數(shù))

注:
如果是這種情況下:

struct A {char s;int a;double b; };

則char s 與int a 合并后的字節(jié)總署為5<8,所以char s與int a 合并后再與8字節(jié)對(duì)齊,所以該結(jié)構(gòu)體的字節(jié)數(shù)為16,而不是24;
下面看一個(gè)例子:

#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; // 20 bytescout << "sizeof(a) = " << sizeof(a) << endl;cout << "sizeof(B) = " << sizeof(B) << endl; // 20 bytesa.print();//定義結(jié)構(gòu)體指針p指向A對(duì)象a,B* p = reinterpret_cast<B*>(&a);//通過(guò)結(jié)構(gòu)體指針p來(lái)操作對(duì)象a的內(nèi)容分p->i = 1;p->j = 2;p->c = 'c';p->d = 3;a.print();p->i = 100;p->j = 200;p->c = 'C';p->d = 3.14;a.print();return 0; }

運(yùn)行結(jié)果如下:

注意:以上是在linux上用gcc編譯器進(jìn)行編譯,所以結(jié)構(gòu)體的對(duì)齊方式是以4字節(jié)的對(duì)齊的,所以結(jié)果為20字節(jié),如果放到vs上編譯,那么該結(jié)構(gòu)體的大小就為24字節(jié)。

同時(shí),我們可以看出,我們可以通過(guò)將結(jié)構(gòu)體指針指向類對(duì)象來(lái)直接操作對(duì)象,這也說(shuō)明了,class是一種特殊的結(jié)構(gòu)體!!!

結(jié)論:
運(yùn)行時(shí)的對(duì)象,退化為結(jié)構(gòu)體的形式:

  • 所有成員變量在內(nèi)存中依次排布
  • 成員變量間可能存在內(nèi)存空隙
  • 可以通過(guò)內(nèi)存地址直接訪問(wèn)成員變量
  • 訪問(wèn)權(quán)限關(guān)鍵字在運(yùn)行時(shí)失效
  • 類中的成員函數(shù)位于代碼段中
  • 調(diào)用成員函數(shù)時(shí),對(duì)象地址作為參數(shù)隱式傳遞
  • 成員函數(shù)通過(guò)對(duì)象地址訪問(wèn)成員變量
  • C++語(yǔ)法規(guī)則隱藏了對(duì)象地址的傳遞過(guò)程
  • 下面再看一個(gè)例子,來(lái)探討C++中對(duì)象的本質(zhì):

    以下C程序是用來(lái)模擬C++中的對(duì)象模型的:
    50-2.h為:

    #ifndef _50_2_H_ #define _50_2_H_typedef void Demo; //定義Demo為一個(gè)void類型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 <stdio.h> #include "50-2.h"int main() {Demo* d = Demo_Create(1, 2); // Demo* d = new Demo(1, 2);printf("d.mi = %d\n", Demo_GetI(d)); // d->getI();printf("d.mj = %d\n", Demo_GetJ(d)); // d->getJ();printf("Add(3) = %d\n", Demo_Add(d, 3)); // d->add(3);// d->mi = 100;Demo_Free(d);return 0; }

    以上c程序,實(shí)現(xiàn)了C++對(duì)象的概念,等價(jià)于下面的C++程序:

    #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;cout << "d.getI() = " << d.getI() << endl;cout << "d.getJ() = " << d.getJ() << endl;cout << "d.add(3) = " << d.add(3) << endl;return 0; }

    總結(jié):

  • C++中的類對(duì)象在內(nèi)存布局上與結(jié)構(gòu)體相同
  • 成員變量和成員函數(shù)在內(nèi)存中是分開(kāi)存放的
  • 訪問(wèn)權(quán)限關(guān)鍵字在運(yùn)行時(shí)失效
  • 調(diào)用成員函數(shù)時(shí),對(duì)象地址作為參數(shù)隱式傳遞
  • 想獲得各種學(xué)習(xí)資源以及交流學(xué)習(xí)的加我:
    qq:1126137994
    微信:liu1126137994
    可以共同交流關(guān)于嵌入式Linux,操作系統(tǒng),C++語(yǔ)言,C語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)與算法等技術(shù)問(wèn)題。

    總結(jié)

    以上是生活随笔為你收集整理的【C++深度剖析教程28】C++对象模型分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。