楼主的问题很经典,可以看出是动了脑筋了。
问题的关键出在这里,a=b;后,a的地址和b相同,a确实已经指向b所指向的内存块,但是这个内存块究竟是调用函数的?
实际上是这样的,对于普通函数,函数调用取决于对象命名的变量类型;而在利用多态(C++中通过虚函数实现)时,调用哪个函数取决于对象在继承链中的位置,与该对象命名的变量类型无关。
这样就好分析楼主的代码了:
例1中a=b;后,a的地址和b相同,但对普通函数sayhiA(), sayhiB()的调用取决于a命名时的变量类型A*,因此只能调用sayhiA();而对虚函数 sprint()的调用取决于b在继承链中的位置,即类型B*,因此调用B中的sprint()。
同理,例2中b1命名时的变量类型为B*,因此调用B的普通函数sayhiA(), sayhiB();而对虚函数 sprint()的调用取决于b1 = (B*)a1;后在继承链中的位置,即类型A*,因此调用A中的sprint()。
这个不是你想的那样简单, C++中包含虚函数的类都有一个虚表的,这个虚表中放置了虚函数的地址,可以看《C++编程思想》。
你可以把B类中重载sayhiA方法, 通过:
A *a = new B();
a->sayhiA可以调用到B里面的方法
你在调试模式下试试
B * b = new B();
A * a = new A();
有什么区别。
实际上是b中包含一个a的实例,但是a只能是a的实例。所以就有你所说的情况。