虚函数,直接上个代码吧,这份代码很长,因为其中研究了一下虚函数的实现,虽说好像什么也没懂。
#include <iostream> #include <stdio.h> using namespace std; class Base { public: Base() {} virtual ~Base() {} void non_virtual_show() { cout << "it shows I am a Base(non_virtual)" << endl; } virtual void virtual_show() { cout << "it shows I am a Base(virtual)" << endl; } virtual void virtual_show_1() {} virtual void virtual_show_2() { cout << "successfully call virtual_show_2 in base" << endl; } }; class Derive_1 : public Base { public: void non_virtual_show() { cout << "it shows I am a Derive_1(non_virtual)" << endl; } virtual void virtual_show() { cout << "it shows I am a Derive_1(virtual)" << endl; } virtual void virtual_show_1() {} virtual void virtual_show_2() { cout << "successfully call virtual_show_2 in derive_1" << endl; } }; int main() { //PART 1 without pointer Base b1; Derive_1 d1; b1.non_virtual_show(); b1.virtual_show(); d1.non_virtual_show(); d1.virtual_show(); cout << endl; //PART 2 with pointer Base *p1 = new Base; Base *p2 = new Derive_1; Derive_1 *p3 = new Derive_1; //Derive_1 *p4 = new Base; invalid conversion p1->non_virtual_show(); p1->virtual_show(); p2->non_virtual_show(); p2->virtual_show(); cout << endl; //PART 3 address void (Base::*B_pointer)(); B_pointer = &Base::non_virtual_show; printf("%p\n", B_pointer); B_pointer = &Base::virtual_show; printf("%p\n", B_pointer); B_pointer = &Base::virtual_show_1; printf("%p\n", B_pointer); B_pointer = &Base::virtual_show_2; printf("%p\n", B_pointer); cout << endl; void (Derive_1::*D_pointer)(); D_pointer = &Derive_1::non_virtual_show; printf("%p\n", D_pointer); D_pointer = &Derive_1::virtual_show; printf("%p\n", D_pointer); D_pointer = &Derive_1::virtual_show_1; printf("%p\n", D_pointer); D_pointer = &Derive_1::virtual_show_2; printf("%p\n", D_pointer); cout << endl; //PART 4 call the virtual function through their address void (Base::*pointer1)(); Base *p4 = new Derive_1; pointer1 = &Base::non_virtual_show; (p4->*pointer1)(); pointer1 = &Base::virtual_show; printf("%p\n", pointer1); pointer1 = &Base::virtual_show_1; printf("%p\n", pointer1); pointer1 = &Base::virtual_show_2; printf("%p\n", pointer1); (p4->*pointer1)(); (p4->*(&Base::virtual_show_2))(); (p4->Base::virtual_show_2)(); p4->Base::virtual_show_2(); //pointer1 = &Derive_1::non_virtual_show; cannot convert 'void (Derive_1::*)' to 'void (Base::*)()' in assignment //pointer1 = &Derive_1::virtual_show; cannot convert 'void (Derive_1::*)' to 'void (Base::*)()' in assignment cout << endl; void (Base::*pointer2)(); Derive_1 *p5 = new Derive_1; pointer2 = &Base::non_virtual_show; (p5->*pointer2)(); pointer2 = &Base::virtual_show; printf("%p\n", pointer2); pointer2 = &Base::virtual_show_1; printf("%p\n", pointer2); pointer2 = &Base::virtual_show_2; printf("%p\n", pointer2); (p5->*pointer2)(); (p5->*(&Base::virtual_show_2))(); (p5->Base::virtual_show_2)(); p5->Base::virtual_show_2(); cout << endl; void (Derive_1::*pointer3)(); Derive_1 *p6 = new Derive_1; pointer3 = &Base::non_virtual_show; (p6->*pointer3)(); pointer3 = &Base::virtual_show; printf("%p\n", pointer3); pointer3 = &Base::virtual_show_1; printf("%p\n", pointer3); pointer3 = &Base::virtual_show_2; printf("%p\n", pointer3); (p6->*pointer3)(); (p6->*(&Base::virtual_show_2))(); (p6->Base::virtual_show_2)(); p6->Base::virtual_show_2(); return 0; }输出结果:
这似乎说明,虚函数的所谓地址只是virtual table中的相对地址(猜测是下标),因为间隔都是一样的,而且基类和派生类的相对地址是一样的(但这并不能说明地址一样,只是相对于virtual table起始距离一样)。不知道这种情况应该怎么解释。
原文:http://blog.csdn.net/u012925008/article/details/44575335