【C++深度剖析教程29】C++对象模型分析下
生活随笔
收集整理的這篇文章主要介紹了
【C++深度剖析教程29】C++对象模型分析下
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
加qq1126137994,微信:liu1126137994 一起學習更多技術!!!
今天來繼續學習C++對象模型!
下面來寫一個程序分析C++的繼承類的模型:
#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; //模擬C++中的指向虛函數表的指針int mi;int mj;int mk; };int main() {cout << "sizeof(Demo) = " << sizeof(Demo) << endl; // 加上虛函數virtual后,大小變為12//因為編譯器發現是虛函數的時候,會自動//生成一個指針指向虛函數表cout << "sizeof(Derived) = " << sizeof(Derived) << endl; Derived d(1, 2, 3);Test* p = reinterpret_cast<Test*>(&d); //p與d類型不同,需要用reinterpret_cast進行類型轉換cout << "Before changing ..." << endl;d.print();p->mi = 10; //p作為外界的結構體竟然可以訪問d的變量,說明p的內存結構與d的相同p->mj = 20;p->mk = 30;cout << "After changing ..." << endl;d.print();return 0; }(注意以上程序用編譯器是gcc編譯器,所以結構體的字節對齊是4字節默認)
運行結果為:
那么久引出了問題:C++多態的實現原理是什么?
C++多態的實現原理:
如下圖:
virtual成員函數,會被編譯器放進虛函數表中
存在虛函數時,每個對象中都有一個指向虛函數表的指針
我們會發現,虛函數的調用過程比普通函數的調用過程復雜,所以虛函數的執行效率低于普通成員函數:
下面給出用C語言實現的C++中的虛函數表的相關概念:
51-2.h為:
51-2.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. 定義虛函數表數據結構 {int (*pAdd)(void*, int); // 3. 虛函數表里面存儲什么??? };struct ClassDemo {struct VTable* vptr; // 1. 定義虛函數表指針 ==》 虛函數表指針類型???int mi;int mj; };struct ClassDerived {struct ClassDemo d;int mk; };static struct VTable g_Demo_vtbl = //static關鍵字將該虛函數表隱藏在當前文件內,外部不可見//類似于C++中虛函數表是自動生成的,外部不可見。 {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. 關聯對象和虛函數表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. 定義虛函數表中指針所指向的具體函數 static int Demo_Virtual_Add(Demo* pThis, int value) {struct ClassDemo* obj = (struct ClassDemo*)pThis;return obj->mi + obj->mj + value; }// 5. 分析具體的虛函數!!!! 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; }總結:
想獲得各種學習資源以及交流學習的加我:
qq:1126137994
微信:liu1126137994
可以共同交流關于嵌入式Linux,操作系統,C++語言,C語言,數據結構與算法等技術問題。
總結
以上是生活随笔為你收集整理的【C++深度剖析教程29】C++对象模型分析下的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思科常用命令
- 下一篇: s3c2440移植MQTT