c++对象模型
来源:互联网 发布:软件框架图 编辑:程序博客网 时间:2024/06/08 19:56
最近看了本 《c++ 对象模型》的书,收益良多。讲了c++对象中成员的分布,虚函数表等。
先看图
类的层次结构
dev类等成员分布
下面是代码,获取成员数据都是通过内存偏移,所以即使是父类的私有方法获成员,都可以访问到,只能说指针太强大了
typedef void(*Fun)(void); //void类型的函数指针 //适用于无实例对象,例如全局函数等// ------------------------------------------------ test1 -------------------------class Tmp{public:short a;int b;double c;};class Base{public:Base():base1Num(123) { cout << "Base::Base" << endl; }virtual ~Base() { cout << "Base::~Base" << endl; }virtual void f() { cout << "Base::f" << endl; }virtual void g() { cout << "Base::g" << endl; }virtual void h() { cout << "Base::h" << endl; }void ooo(){ cout << "Base::ooo" << endl; }void ppp(){ cout << "Base::ppp" << endl; }private:virtual void j() { cout << "Base::j" << endl; }int base1Num;};class Base2{public:Base2():base2Num(456) { cout << "Base2::Base2" << endl; }virtual ~Base2() { cout << "Base2::~Base2" << endl; }virtual void x() { cout << "Base2::x" << endl; }virtual void y() { cout << "Base2::y" << endl; }void rrr() { cout << "Base2::rrr" << endl; }void sss() { cout << "Base2::sss" << endl; }private:virtual void z() { cout << "Base2::z" << endl; }int base2Num;};class dev : public Base , public Base2{public:virtual void f() { cout << "dev::f" << endl; }virtual void k() { cout << "dev::k" << endl; }virtual void z() { cout << "dev::z" << endl; }public:int num;char* str;dev* child;Tmp tmp;//double price; //加了个8个字节的double,字节对齐时会占用更多字节,对象大小增大};void testVirtualTable(){//Base b1;//b1.j(); //compile errordev d;d.num = 100;d.str = "hello world";//d.child = new dev;//d.child->num = 500;d.tmp.a = 31;d.tmp.b = 777;d.tmp.c = 888;//d.f(); //compile errorcout << "虚函数表地址:" << (int*)(&d) << endl;cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&d) << endl;printf("\n");//通过函数指针访问到私有的j(), j()对于对象来讲本来是不可见的,指针太强大Fun pFun2 = nullptr;//第一个虚函数表指针指向//pFun2 = (Fun)*((int*)*(int*)(&d) + 0); //Base::~Base //析构不能调//pFun2();pFun2 = (Fun)*((int*)*(int*)(&d) + 1); //dev::f //dev重写Base的fpFun2();pFun2 = (Fun)*((int*)*(int*)(&d) + 2); //Base::gpFun2();pFun2 = (Fun)*((int*)*(int*)(&d) + 3); //Base::hpFun2();pFun2 = (Fun)*((int*)*(int*)(&d) + 4); //Base::jpFun2();pFun2 = (Fun)*((int*)*(int*)(&d) + 5); //dev::kpFun2();//Base base1Num的存储偏移在虚函数表指针的下4个字节int base1Num = (int)*((int*)(&d) + 1);printf("--- base1Num:%d\n", base1Num); //123printf("\n");//第二个虚函数表指针指向//pFun2 = (Fun)*((int*)*((int*)(&d) + 1) + 0); //Base2::~Base2 //析构不能调//pFun2();pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 1);//Base2::ypFun2();pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 2); //Base2::ypFun2();pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 3); //dev::z //dev重写Base2的zpFun2();//Base2 base2Num的存储偏移在虚函数表指针的下4个字节int base2Num = (int)*((int*)(&d) + 3);printf("--- base2Num:%d\n", base2Num); //456printf("\n");//通过地址获取成员变量int num = (int)*((int*)(&d) + 4);char* str = (char*)*((int*)(&d) + 5);printf("--- dev.num:%d\n", num);printf("--- dev.str:%s\n", str);printf("\n");//(base vtp + base1num + base2 vtp + base2num + dev::num + dev::str + dev::dev*) * 4 = 28//printf("--- dev size : %d\n", sizeof(dev)); //28//如果 dev 加多个 double 型成员,因为字节对齐是更具最大元素来对界,会得到sizeof为40,参考ByteAlign.cpp; printf("--- Tmp size : %d\n", sizeof(Tmp));printf("--- dev size : %d\n", sizeof(dev));printf("--- str:0x%x\n", str);Tmp* tmp = (Tmp*)&(*((int*)(&d) + 7));printf("--- tmp:0x%x\n", tmp);printf("--- tmp.b:%d\n", tmp->b);short tmpA = (short)*((int*)(&d) + 7);printf("--- tmpA:%d\n", (int)tmpA);int tmpB = (int)*((int*)(&d) + 8);printf("--- tmpB:%d\n", tmpB);int tmpC = (int)*((int*)(&d) + 9);printf("--- tmpC:%d\n", tmp->c);//dev* child = (dev*)*((int*)(&d) + 4);//printf("--- child num:%d\n", child->num);//Base* b2 = new dev();////b2->k(); //compile error,父类指针无法call子类特有的虚函数////通过函数指针访问到子类特有的虚函数k(), 指针太强大//Fun pFun3 = (Fun)*((int*)*(int*)b2 + 4);//pFun3();}
运行结果
0 0
- Objective-C对象模型
- Objective-C对象模型
- objective C 对象模型
- C ++ 对象模型
- Objective-C 对象模型
- 【C++】对象模型
- Objective-C对象模型
- C/C++的对象模型
- Objective-C的对象模型
- 图解Objectvie-C对象模型
- C/C++的对象模型
- Objective-C对象模型--类对象和元类对象
- 深度探索C++对象模型
- Objective-C 对象和消息模型
- Objective-C对象模型及应用
- Objective-C对象模型及应用
- Objective-C对象模型及应用
- Objective-C对象模型及应用
- 【诚邀您免费报名】第十二届中国软件工程大会CCSE 2015
- Patrick and Shopping(模拟)
- 常用算法二(动态规划)
- DateTimePicker控件只显示年份
- MySQL-----MySQL中max函数查询最大值问题
- c++对象模型
- (5.1)uboot详解——时钟分频
- 前端多文件上传
- 地图定位
- -objc, ARC MRC混编,Undefined symbols for architecture x86_64 整理
- hdu5521 修改的mlog(n)的Dijkstra算法 2015ACM沈阳现场赛题
- 常用算法三(贪心算法)
- iOS中 target/action 设计模式
- 半平面求交——放置守卫