c++对象模型
2015-11-21 10:09
357 查看
最近看了本 《c++ 对象模型》的书,收益良多。讲了c++对象中成员的分布,虚函数表等。
先看图
类的层次结构
dev类等成员分布
下面是代码,获取成员数据都是通过内存偏移,所以即使是父类的私有方法获成员,都可以访问到,只能说指针太强大了
运行结果
先看图
类的层次结构
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 error dev 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 error cout << "虚函数表地址:" << (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的f pFun2(); pFun2 = (Fun)*((int*)*(int*)(&d) + 2); //Base::g pFun2(); pFun2 = (Fun)*((int*)*(int*)(&d) + 3); //Base::h pFun2(); pFun2 = (Fun)*((int*)*(int*)(&d) + 4); //Base::j pFun2(); pFun2 = (Fun)*((int*)*(int*)(&d) + 5); //dev::k pFun2(); //Base base1Num的存储偏移在虚函数表指针的下4个字节 int base1Num = (int)*((int*)(&d) + 1); printf("--- base1Num:%d\n", base1Num); //123 printf("\n"); //第二个虚函数表指针指向 //pFun2 = (Fun)*((int*)*((int*)(&d) + 1) + 0); //Base2::~Base2 //析构不能调 //pFun2(); pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 1);//Base2::y pFun2(); pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 2); //Base2::y pFun2(); pFun2 = (Fun)*((int*)*((int*)(&d) + 2) + 3); //dev::z //dev重写Base2的z pFun2(); //Base2 base2Num的存储偏移在虚函数表指针的下4个字节 int base2Num = (int)*((int*)(&d) + 3); printf("--- base2Num:%d\n", base2Num); //456 printf("\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(); }
运行结果
相关文章推荐
- HDU4121 UVa1589 Xiangqi 解题报告
- [黑马IOS自学第六篇]C语言指针,数组指针,字符指针学习
- [黑马IOS自学第五篇]C语言二维数组,排序法学习
- C语言拾遗
- C++中sort函数用法
- Jni :三维数组处理方法 ,以整形三维数组为例 C++实现
- C语言:设置自动关机程序:2分钟之后关机,请输入\"我好帅\"三个字解除\n"
- 深入理解C++中的mutable关键字
- 指针与数组的关联3 --声明
- C++中消除CString类型字符串中的标点符号
- C,C++如何和OC混用
- C++ GUI Qt4编写的文本编辑器
- 《c语言从入门到精通》看书笔记——第15章 存储管理
- 《c语言从入门到精通》看书笔记——第14章 文件
- Google C++ Testing Framework Primer
- 《c语言从入门到精通》看书笔记——第12章 位运算
- 《c语言从入门到精通》看书笔记——第10章 指针
- 《c语言从入门到精通》看书笔记——第9章 函数
- 【C语言】 实现memmove
- 《c语言从入门到精通》看书笔记——第8章 数组