虚函数,直接上个代码吧,这份代码很长,因为其中研究了一下虚函数的实现,虽说好像什么也没懂。
#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