1. 虚函数的实现原理
在C++的类内会维护一个虚表,同时还有一个虚指针。可以通过VC 6.0来观看类的虚函数表。
#include#include class A{public : virtual void f(){ std::cout<<"This is A's f"<
C++的类中第一个变量就是虚指针。其中a类的地址是0x0012ff44,紧接着就是虚指针。而b类的地址为0x0012ff40,由此可见a类内只有虚指针这一个变量。
解决了虚指针的问题,现在正式进入虚函数表。从代码可以看到,A类内定义了两个虚函数 f() 和 g() ,B类继承A类,实现了虚函数 f() ,并没有实现 g() , C类正好相反。D类暂时不讨论,她负责解释多重继承产生二义性的问题。
通过VC 6.0的调试可以看到各个虚函数的地址,如图。
可以看到,a类的虚指针里有两个虚函数地址分别为0x004012cd(A::f(void))和0x004011b8(A::g(void))。而b类继承a类,由于b类只实现了虚函数f(),所以b类的虚指针内的B::f(void)是指向b类内实现的虚函数,而g()函数还是指向A类的A::g(void)函数。C类则与B类类似。
总结下,C++的类是通过一个虚指针(__vfptr)指向一个虚函数表来实现虚函数的功能,从而实现动态的多态。
2. 通过子类调用父类”们“方法
依然是刚才那段代码,我在B、C、D类内分别写了test(),来调用父类”们“的方法。
#include#include class A{public : virtual void f(){ std::cout<<"This is A's f"<
在运行时对继承方式做了修改,通过网络图和结果显示。具体请看下图。
总结下,不管怎么继承子类都可以调用父类的方法,但是当子类B、C私有继承类A时,类B、C的子类D则不能调用类A的方法。