C++ 对象模型学习记录(2)--- 第3章 data语义学
2011-08-31 13:41
351 查看
1. 关于sizeof的运行结果
#include <iostream> //在GCC 中 using namespace std; class X{}; class Y :public X{}; class Z : public X{}; class W :public Y,public Z{}; int main() { cout << sizeof(X) << endl;//1 cout << sizeof(Y) << endl;//1 cout << sizeof(Z) << endl;//1 cout << sizeof(W) << endl;//2 return 0; }而在vs 2010中是默认的编译器中
#include <iostream> using namespace std; class X{}; class Y :public X{}; class Z : public X{}; class W :public Y,public Z{}; int main() { cout << sizeof(X) << endl;//1 cout << sizeof(Y) << endl;//1 cout << sizeof(Z) << endl;//1 cout << sizeof(W) << endl;//1 return 0; }加了虚继承后,GCC和vs的竟然相同了,总的来说就是有了 virtual 继承,加了一个vptr指针和指向的是一个 要么是virtual base table,要么是offset
#include <iostream> using namespace std; class X{}; class Y :public virtual X{}; class Z : public virtual X{}; class W :public Y,public Z{}; int main() { cout << sizeof(X) << endl;//1 cout << sizeof(Y) << endl;;//4 cout << sizeof(Z) << endl;//4 cout << sizeof(W) << endl;//8 return 0; }2. 关于指向data member 数据成员的指针
#include <iostream> #include <stdio.h> using namespace std; struct Base1{int val1; }; struct Base2{int val2; }; struct Derived : Base1,Base2 {};
//Derived2为了和Derived比较
struct Derived2 : Base1,Base2{int val3;}; void func1(int Derived::*dmp,Derived *pd) { //期望传进来的是一个"指向 derived class 的member "的指针 //如果传进来的是“指向base class 的member”的指针, //结果如何? cout << pd->*dmp << endl; } void func2(Derived *pd) { //bmp将成为1 int Base2::* bmp = &Base2::val2;//Base2::* 型的变量 cout << bmp << endl; printf("~~~~~~~~~~~~~~~~~~~%d\n",bmp); func1(bmp,pd); //这里必须由编译器内部转换 // func1(,pd); } int main() { Base1 base1; base1.val1 = 1; Base2 base2; base2.val2 = 2; Derived d; Derived *p = &d; func2(p); cout << "-------------------" << endl; //以下结果都是0 printf("&Base1::val1 = %p\n",&Base1::val1); printf("&Base2::val2 = %p\n",&Base2::val2); printf("&Derived::val1 = %p\n",&Derived::val1); printf("&Devrived::val2 = %p\n",&Derived::val2); cout << &Base1::val1 << endl; cout << &Base2::val2 << endl; cout << &Derived::val1 << endl; cout << &Derived::val2 << endl; cout << "--------------" << endl; printf("&Derived2::val1 = %p\n",&Derived2::val1); printf("&Devrived2::val2 = %p\n",&Derived2::val2); printf("&Derived2::val = %p\n", &Derived2::val3 ); cout << &Derived2::val1 << endl; cout << &Derived2::val2 << endl; cout << &Derived2::val3 << endl; return 0; }运行结果如下:GCC和VC下都是同样的结果可以看出的是 在c++中cout 和printf 输出的结果竟然还是不一样的 == ,应该是 C++重载了 <<运算符,使<<能够适应各种输出的原因吧
int Base2::* bmp = &Base2::val2;//Base2::* 型的变量 cout << bmp << endl;
通过 cout 可以看出这里输出的就是1,但是 在GCC下 不能转化为 int型的,所以才有了调用 func1(bmp,pd); 并在函数中 cout << pd->*dmp << endl; 时得到了 一个随机数
对于C++对象模型中所说的 &Base1::val1 中val 指的是 val在类的对象中的偏移量问题,只能通过printf("&Base1::val1 = %p\n",&Base1::val1);看到,cout 方式可能还是因为重载的缘故吧:所有的输出都是1(不知道原因,可能不是偏移量了吧)
printf("&Devrived::val2 = %p\n",&Derived::val2); 对于&Derived::val2实际的偏移量应该是4,可能由于编译器的优化,输出为0了。。(怎么优化的? 想不明白)
书中以 printf("&Derived2::val = %p\n", &Derived2::val3 ); 打印出了 val3的偏移量为8,可以看出
3. 那个point2d,3d问题
#include <iostream>#include <stdio.h>using namespace std;class Point3d{public:virtual ~Point3d();Point3d(float a,float b,float c){x = a;y = b;z = c;// origin(x,y,z);}static Point3d origin;static void f(){//error: request for member 'x' in 'Point3d::origin',//which is of non-class type 'Point3d()'//printf("&origin.x = %p\n",&(origin.x));//printf("&origin.y = %p\n",&origin.y);//printf("&origin.z = %p\n",&origin.z);// printf("&origin = %p\n",&origin);}float x,y,z;};int main(){float f = 1.0;cout << sizeof(f) << endl;cout << sizeof(float) << endl;cout << sizeof(double) << endl;printf("&Point3d::x = %p\n",&Point3d::x);//计算的是偏移量 4printf("&Point3d::y = %p\n",&Point3d::y);//4 ,结果是8printf("&Point3d::z = %p\n",&Point3d::z);//4 结果是C(12)cout << "&Point3d::x = " << &Point3d::x << endl;cout << "&Point3d::y = " << &Point3d::y << endl;cout << "&Point3d::z = " << &Point3d::z << endl;//undefined reference to `Point3d::origin'// printf("&origin.x = %p\n",&(Point3d::origin.x));// printf("&origin.y = %p\n",&Point3d::origin.y);// printf("&origin.z = %p\n",&Point3d::origin.z);Point3d p();//Point3d::f();return 0;}
木有打印出来 origin.x ,错误是
(1) //undefined reference to `Point3d::origin' ,
(2)//error: request for member 'x' in 'Point3d::origin',
//which is of non-class type 'Point3d()'将 virtual ~Point3d(); 去掉虚函数~,变为 Point3d()并完成初始化后:Point3d Point3d::origin(1,1,1);
#include <iostream>#include <stdio.h>using namespace std;class Point3d{public:~Point3d(){};Point3d(float a,float b,float c){x = a;y = b;z = c;}static Point3d origin;float x,y,z;};Point3d Point3d::origin(1,1,1);int main(){float f = 1.0;cout << sizeof(f) << endl;cout << sizeof(float) << endl;cout << sizeof(double) << endl;printf("&Point3d::x = %p\n",&Point3d::x);printf("&Point3d::y = %p\n",&Point3d::y);printf("&Point3d::z = %p\n",&Point3d::z);cout << "&Point3d::x = " << &Point3d::x << endl;cout << "&Point3d::y = " << &Point3d::y << endl;cout << "&Point3d::z = " << &Point3d::z << endl;//undefined reference to `Point3d::origin'printf("&origin.x = %p\n",&(Point3d::origin.x));printf("&origin.y = %p\n",&Point3d::origin.y);printf("&origin.z = %p\n",&Point3d::origin.z);//Point3d::f();return 0;}结果如下:对比与 两个图中的 &Point3d::x 值得出结论:在GCC编译器中,如果加了 virtual ,它的对象布局中应该是 vptr在 数据成员的上面而不是像 c++对象模型 cfont 编译器中在数据成员下面
相关文章推荐
- 深入C++对象模型学习笔记 第3章 Data 语意学
- C++ 对象模型学习记录(3)--- 第1章 关于对象(未完)
- C++ 对象模型学习记录(1)--- 第2章 构造函数语义学
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(中)
- C++学习之C++对象内存模型(上)
- C++对象模型学习——Data语意学
- 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记
- 深度探索C++对象模型复习和学习 第四章:Function 语意学 (The Semantics of Function)
- C++对象模型学习系列(一)
- MOSS Search学习记录(十):MOSS Visual How To使用SharePoint Server 2007搜索对象模型编程创建搜索查询
- 学习《深入理解C++对象模型》小结
- C++对象模型学习笔记(二)--默认构造函数
- C++对象模型 学习笔记01
- C++ 对象模型 学习笔记(1)
- boolan——c++学习笔记之多态对象模型
- 深度探索c++对象模型学习笔记
- C++对象模型学习
- 【C++对象模型】第三章 Data语义学
- C++学习5 对象模型