http://blog.csdn.net/wufen1103/article/details/6548308
class Father
{
public:
name()
{printf("father name/n");};
virtual call()
{printf("father call/n");};
};
class Son: public Father
{
public:
name()
{printf("Son name/n");};
virtual call()
{printf("Son call/n");};
};
main()
{
Son *Son1=new Son();
Father *father1=(Father *)Son1;
father1->call();
father1->name();
((Son *)(father1))->call();
((Son *)(father1))->name();
Father *f2=new Father();
Son *s2=(Son*)f2;
s2->call();
s2->name();
((Father *)(s2))->call();
((Father *)(s2))->name();
}
输出结果:
Son call
father name
Son call
Son name
father call
Son name
father call
father name
为什么呢????
class Father
{
public:
name()
{printf("father name/n");};
virtual call()
{printf("father call/n");};
};
class Son: public Father
{
public:
name()
{printf("Son name/n");};
virtual call()
{printf("Son call/n");};
};
main()
{
Son *Son1=new Son(); //new一个son对象,此时son对象内存关联了一个虚函数指针表
执行Son *Son1=new Son();后内存情况
Father *father1=(Father *)Son1; //强制转换为father
看到没,虚函数表V-Table里的call地址没,没变哦。。。
Ps:此时,你有没有产生什么疑问呢,没错,那普通函数在内存的存储空间呢??
father1->call(); //强制转换的结果是son内存空间扩大了,关联的虚函数指针表还是原来son的,所以调用来son的call;
father1->name(); //普通函数,函数的存储空间并不是在new处理的那一块空间,c++把普通函数统一放在一块内存里进行管理,所以此时我们就调用的是father的name函数。
此时我们看一下name函数的地址 是不是和new出来的father的地址有很大的不同呢,呵呵,这就验证了c++把普通函数放在不是new出来的那一块内存进行管理。
((Son *)(father1))->call(); //又将原来son对象强制转换成的father对象强制转换为son,此时,内存空间并没有改变,还是只有father基类的空间大小,此时调用的是son的call函数。
((Son *)(father1))->name(); //同father1->name();调用来son的name
Father *f2=new Father();//new一个father对象,此时father对象内存关联了一个虚函数指针表
Son *s2=(Son*)f2; //强制转换为son对象,
s2->call(); //猜下调用了谁的call,没错,father的
s2->name(); //这个呢,没错,son的
((Father *)(s2))->call(); //这个呢,没错,father的call();
((Father *)(s2))->name(); //对了,调用来father的name函数
}