日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

C++对象模型分析

發(fā)布時間:2025/4/5 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++对象模型分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1 class本質(zhì)分析
      • 1.1 class本質(zhì)
    • 2 非繼承對象模型分析
      • 2.1 非繼承對象模型分析
    • 3 繼承對象模型分析
      • 3.1 繼承對象模型
      • 3.2 多態(tài)對象模型

1 class本質(zhì)分析

1.1 class本質(zhì)

class是一種特殊的struct:

  • 在內(nèi)存中class依舊可以看作變量的集合。
  • class與struct遵循相同的內(nèi)存對齊規(guī)則。
  • class中的成員函數(shù)與成員變量是分開存放的:
    • 每個對象有獨(dú)立的成員變量。
    • 所有對象共享類中的成員函數(shù)。

值得思考的問題:

對象內(nèi)存布局初探:

#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();B* p = reinterpret_cast<B*>(&a);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é)構(gòu)體的形式:

  • 所有成員變量在內(nèi)存中依次排布。
  • 成員變量可能存在內(nèi)存空隙。
  • 可以通過內(nèi)存地址直接訪問成員變量。
  • 訪問權(quán)限關(guān)鍵字在運(yùn)行時失效。

2 非繼承對象模型分析

2.1 非繼承對象模型分析

對象模型分析:

  • 類中的成員函數(shù)位于代碼段中。
  • 調(diào)用成員函數(shù)時對象地址作為參數(shù)隱式傳遞。
  • 成員函數(shù)通過對象地址訪問成員變量。
  • C++語法規(guī)則隱藏了對象地址的傳遞過程。

下面用C語言實(shí)現(xiàn)如下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; }

demo.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

demo.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; }

3 繼承對象模型分析

3.1 繼承對象模型

繼承對象模型:

  • 在C++編譯器的內(nèi)部類可以理解為結(jié)構(gòu)體。
  • 子類是由父類成員疊加子類新成員得到的。

3.2 多態(tài)對象模型

C++多態(tài)的實(shí)現(xiàn)原理:

  • 當(dāng)類中聲明虛函數(shù)時,編譯器會在類中生成一個虛函數(shù)表。
  • 虛函數(shù)表是一個存儲成員函數(shù)地址的數(shù)據(jù)結(jié)構(gòu)。
  • 虛函數(shù)表是由編譯器自動生成與維護(hù)的。
  • virtual成員函數(shù)會被編譯器放入虛函數(shù)表中。
  • 存在虛函數(shù)時,每個對象中都有一個指向虛函數(shù)表的指針(位于最前面)。



繼承對象模型示例:

#include <iostream> #include <string>using namespace std;class Demo { protected:int mi;int mj; public:virtual void print(){cout << "mi = " << mi << ", "<< "mj = " << mj << endl;} };class Derived : public Demo {int mk; public:Derived(int i, int j, int k){mi = i;mj = j;mk = k;}void print(){cout << "mi = " << mi << ", "<< "mj = " << mj << ", "<< "mk = " << mk << endl;} };struct Test {void* p;int mi;int mj;int mk; };int main() {cout << "sizeof(Demo) = " << sizeof(Demo) << endl; cout << "sizeof(Derived) = " << sizeof(Derived) << endl; Derived d(1, 2, 3);Test* p = reinterpret_cast<Test*>(&d);cout << "Before changing ..." << endl;d.print();p->mi = 10;p->mj = 20;p->mk = 30;cout << "After changing ..." << endl;d.print();return 0; }

用C語言實(shí)現(xiàn)多態(tài)特性:
demo.h:

#ifndef _51_2_H_ #define _51_2_H_typedef void Demo; typedef void Derived;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);Derived* Derived_Create(int i, int j, int k); int Derived_GetK(Derived* pThis); int Derived_Add(Derived* pThis, int value);#endif

demo.c:

#include "51-2.h" #include "malloc.h"static int Demo_Virtual_Add(Demo* pThis, int value); static int Derived_Virtual_Add(Demo* pThis, int value);struct VTable // 2. 定義虛函數(shù)表數(shù)據(jù)結(jié)構(gòu) {int (*pAdd)(void*, int); // 3. 虛函數(shù)表里面存儲什么??? };struct ClassDemo {struct VTable* vptr; // 1. 定義虛函數(shù)表指針 ==》 虛函數(shù)表指針類型???int mi;int mj; };struct ClassDerived {struct ClassDemo d;int mk; };static struct VTable g_Demo_vtbl = {Demo_Virtual_Add };static struct VTable g_Derived_vtbl = {Derived_Virtual_Add };Demo* Demo_Create(int i, int j) {struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo)); if( ret != NULL ){ret->vptr = &g_Demo_vtbl; // 4. 關(guān)聯(lián)對象和虛函數(shù)表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; }// 6. 定義虛函數(shù)表中指針?biāo)赶虻木唧w函數(shù) static int Demo_Virtual_Add(Demo* pThis, int value) {struct ClassDemo* obj = (struct ClassDemo*)pThis;return obj->mi + obj->mj + value; }// 5. 分析具體的虛函數(shù)!!!! int Demo_Add(Demo* pThis, int value) {struct ClassDemo* obj = (struct ClassDemo*)pThis;return obj->vptr->pAdd(pThis, value); }void Demo_Free(Demo* pThis) {free(pThis); }Derived* Derived_Create(int i, int j, int k) {struct ClassDerived* ret = (struct ClassDerived*)malloc(sizeof(struct ClassDerived));if( ret != NULL ){ret->d.vptr = &g_Derived_vtbl;ret->d.mi = i;ret->d.mj = j;ret->mk = k;}return ret; }int Derived_GetK(Derived* pThis) {struct ClassDerived* obj = (struct ClassDerived*)pThis;return obj->mk; }static int Derived_Virtual_Add(Demo* pThis, int value) {struct ClassDerived* obj = (struct ClassDerived*)pThis; return obj->mk + value; }int Derived_Add(Derived* pThis, int value) { struct ClassDerived* obj = (struct ClassDerived*)pThis;return obj->d.vptr->pAdd(pThis, value); }

main.c:

#include "stdio.h" #include "51-2.h"void run(Demo* p, int v) {int r = Demo_Add(p, v);printf("r = %d\n", r); }int main() {Demo* pb = Demo_Create(1, 2);Derived* pd = Derived_Create(1, 22, 333);printf("pb->add(3) = %d\n", Demo_Add(pb, 3));printf("pd->add(3) = %d\n", Derived_Add(pd, 3));run(pb, 3);run(pd, 3);Demo_Free(pb);Demo_Free(pd);return 0; }

參考資料:

  • C++深度解析教程
  • 總結(jié)

    以上是生活随笔為你收集整理的C++对象模型分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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