1、我们先来看第一道:
- #include<iostream>
- using namespace std;
- class A
- {
- public:
- A()
- {
- m_a = 1;
- m_b = 2;
- }
- void fun()
- {
- cout<<m_a<<" "<<m_b<<endl;
- }
- private:
- int m_a;
- int m_b;
- };
- class B
- {
- public:
- B()
- {
- m_c = 3;
- }
- void fun()
- {
- cout<<m_c<<endl;
- }
- private:
- int m_c;
- };
- int main()
- {
- A a;
- B* pb =(B*)(&a);
- pb->fun();
- return 0;
- }
2)我们来分析下:
a:先来看A和B的对象模型:
b:Bl类型的对象pb取a的地址并将其转换成B类型的,因此就有指针pb指向A对象模型的首地址,接着pb调用fun()函数,此时的fun()函数是类B的函数,要输出_c的值就取刚才指向的A中的前四个字节,即_a的值,于是程序运行结果就是1。
2、第二道:
描述:上面例子,让类B公有继承自类A
- #include<iostream>
- using namespace std;
- class A
- {
- public:
- A()
- {
- m_a = 1;
- m_b = 2;
- }
- void fun()
- {
- cout<<m_a<<" "<<m_b<<endl;
- }
- private:
- int m_a;
- int m_b;
- };
- class B:public A
- {
- public:
- B()
- {
- m_c = 3;
- }
- void fun()
- {
- cout<<m_c<<endl;
- }
- private:
- int m_c;
- };
- int main()
- {
- A a;
- B* pb =(B*)(&a);
- pb->fun();
- return 0;
- <span style="color:#009900;">}</span>
2)来分析:
a:先来看对象模型
b:跟上面类似,不过在pb调用fun函数的时候,它会将A的对象模型认为是自己的,在打印_c的时候,因为A中没有第三个值,所以程序运行结果是随机值。
3、将第二道题做些改变:让A中的函数成为虚函数
- #include<iostream>
- using namespace std;
- class A
- {
- public:
- A()
- {
- m_a = 1;
- m_b = 2;
- }
- virtual void fun()
- {
- cout<<m_a<<" "<<m_b<<endl;
- }
- private:
- int m_a;
- int m_b;
- };
- class B:public A
- {
- public:
- B()
- {
- m_c = 3;
- }
- void fun()
- {
- cout<<m_c<<endl;
- }
- private:
- int m_c;
- };
- int main()
- {
- A a;
- B* pb =(B*)(&a);
- pb->fun();
- return 0;
- }
2)程序分析:
a:对象模型分析
b:程序分析:A中的对象模型多了一个虚表指针,在pb调用fun函数的时候,此时因为是虚函数,所以它会去调用实际的对象所指的函数类型,此时它调用的是A类的fun函数,通过虚表指针找到实际的虚函数地址,正是A中的fun函数,因此程序运行结果就是_a,_b的值:1 2
4、这道题是第三题的变形:将B中的函数设为虚函数,而A中的函数设为普通函数
- #include<iostream>
- using namespace std;
- class A
- {
- public:
- A()
- {
- m_a = 1;
- m_b = 2;
- }
- void fun()
- {
- cout<<m_a<<" "<<m_b<<endl;
- }
- private:
- int m_a;
- int m_b;
- };
- class B:public A
- {
- public:
- B()
- {
- m_c = 3;
- }
- virtual void fun()
- {
- cout<<m_c<<endl;
- }
- private:
- int m_c;
- };
- int main()
- {
- A a;
- B* pb =(B*)(&a);
- pb->fun();
- return 0;
- }
2)程序运行结果分析:
a:对象模型的分析
b:程序结果分析:此时pb多了一个虚表指针,当pb调用fun函数的时候,此时pb还是指向A的对象模型,但是,pb会向上挪动四个字节,而访问挪动后的空间,程序必然崩溃。