设计知识点:
指针类型强制转换(挑战你的脑回路)
虚函数表
#include <iostream>
using namespace std;
//m g f j goh //总共有七个,不重复有留个.
/*
依照逻辑来看(仅仅)B对象虚函数表构成.
g
f
j
m
g <这个实际上被重写了>
o
h
*/
class H
{
virtual void M()
{
cout << "H::M" << endl;
}
};
class A
{
//int num;
virtual void g()
{
cout << "A::g" << endl;
}
private:
virtual void f()
{
cout << "A::f" << endl;
}
virtual void j()
{
cout << "A::j" << endl;
}
};
class B : public A,public H
{
void g()
{
cout << "B::g" << endl;
}
virtual void o()
{
cout << "B::o" << endl;
}
virtual void h()
{
cout << "B::h" << endl;
}
/*
virtual void M()
{
cout << "B::M" << endl;
}
*/
virtual void my()
{
cout << "B::my" << endl;
}
};
typedef void(*Fun)(void);
struct HELLO
{
int i = 0;
int ml = 10;
};
//H A B:AH
void main()
{
cout << sizeof(A) << endl;
cout << sizeof(H) << endl;
cout << sizeof(B) << endl;
B b;
Fun pFun;
for (int i = 0; i < 5; i++)
{
pFun = (Fun)*((int*) *(int*)(&b) + i); //等同于 (Fun)*((int*) (*(int*)&b) + i);其中提及到的语法 (int*)p + i 为先进行类型强转
//在进行加法运算.运算完的节骨类型也为强转类型.读这段代码例子,形成自我读代码逻辑加整体概念
pFun();
}
Fun pyuan = (Fun)*(int *)*((int*)(&b) + 1);
pyuan();
/*错误理解:写给自己看备注的笔记
实际上还是概念错误,这里地方实际强转来强转去容易犯晕.
虚表实际上是个二维数组的概念:弄了半天终于弄透了,实际上是换种方式的二维数组.
本来想变换写法的:实际上这个将以为数组首地址强转了.
void *p = (void *)(*((int*)(&b) + 1));
Fun pFun1 = (Fun)p;
*/
//这里运行了B类中的自己的虚函数<非派生>
pFun = (Fun)*((int*)*(int*)(&b) + 5);
pFun();
/*
最终总结:
依题说题<因为这方面是编译器决定的机制:关于虚表是否在对钱内存起始处和虚表相关规则的建立,仅仅依照此代码得到相关结论,理解机制即可>
1.派生类会为每个基类建立不同的虚表一个类一份 //算了,把这种说法枪毙掉,由编译器和平台决定,所幸就具体化来说
1.B类继承了A和H类.依照我内存观察.B类中就分配了8字节存放A和H虚表所在位置地址.<也就是一人四个字节指定它们各自以为数组位置>
2.B类有自己自定义的虚函数,依照我的观察,它机制所幸就将那个函数放到当前对象的A虚表中了.
*/
cin.get();
}
下面链接收藏一篇讲解详细的:可以自行转弯查看:http://blog.csdn.net/haoel/article/details/1948051/