对象模型分析(下)
Posted 学习只为旅行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象模型分析(下)相关的知识,希望对你有一定的参考价值。
对象模型分析(下)
修改Derived类,增加构造函数和成员函数,编译结果大小不变!成员函数存放在代码段!
如果编译器发现类中有虚函数,那么会强行塞一个指针成员变量(不可见但存在),此指针指向虚函数表
给Demo中的print函数加上virtual关键字,再次打印结果:
证实了存在指向虚函数表的指针
#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);
//用于指针间的强制类型转换,p指向d对象内存空间
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语言实现C++“多态”功能:
下面程序重点是实现add函数的多态,就是说传入不同对象指针,就调用不同对象的成员函数!
#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
#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. 定义虚函数表指针 ==》 虚函数表指针类型是什么?在2中定义指针类型
int mi;
int mj;
};
struct ClassDerived
{
struct ClassDemo d;
int mk;
};
//为什么用static?隐藏到当前文件,外部不可访问!
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. 关联对象和虚函数表
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);
}
#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;
}
都是调用run函数,相同的行为不同的结果!成功实现多态
小结
以上是关于对象模型分析(下)的主要内容,如果未能解决你的问题,请参考以下文章