///从网上抄来的,做了点修改,能正确运行出来而已 #include <stdio.h> #include <iostream> using namespace std;
///基类,有2个成员变量width和height,有2个虚函数和一个成员函数 class Shape { public: ?? ?Shape(int a = 0, int b = 0) ?? ?{ ?? ??? ?width = a; ?? ??? ?height =b; ?? ?} ?? ? ?? ?virtual int area() ?? ?{ ?? ??? ?printf("Parent class area:\n"); ?? ??? ?return 0; ?? ?} ?? ? ?? ?virtual void sayHello() ?? ?{ ?? ??? ?printf("Shape..\n"); ?? ?} ?? ? ?? ?void bar() ?? ?{ ?? ??? ?printf("bar fun width:%d\n", width); ?? ?} ?? ? protected: ?? ?int width, height; };
///Shape子类,继承了Shape的width和height,重写了虚函数area和sayHello,重新定义了一个虚函数Call,相当于有3个虚函数 class Rectangle:public Shape { public: ?? ?Rectangle(int a = 0, int b = 0) : Shape(a, b){} ?? ?int area() ?? ?{ ?? ??? ?printf("Rectangle class area:\n"); ?? ??? ?return width * height; ?? ?}
?? ?virtual void sayHello() ?? ?{ ?? ??? ?printf("Rectangle..\n"); ?? ?} ?? ? ?? ?virtual void Call() ?? ?{ ?? ??? ?printf("Rectangle Call....\n"); ?? ?} ?? ? };
///Shape子类,继承了Shape的width和height,重写了虚函数area和sayHello,重新定义了一个虚函数Call,相当于有3个虚函数 class Triangle:public Shape { public: ?? ?Triangle(int a = 0, int b = 0) : Shape(a, b){} ?? ?int area() ?? ?{ ?? ??? ?printf("Triangle class area:\n"); ?? ??? ?return width * height / 2; ?? ?}
?? ?virtual void sayHello() ?? ?{ ?? ??? ?printf("Triangle..\n"); ?? ?} ?? ? ?? ?virtual void Call() ?? ?{ ?? ??? ?printf("Triangle Call....\n"); ?? ?} };
///多肽的调用接口 void test(Shape* shape) { ?? ?shape->bar(); ?? ?shape->area(); ?? ?shape->sayHello(); }
class Shape1 { public: ?? ?Shape1(int a = 0, int b = 0) ?? ?{ ?? ??? ?width = a; ?? ??? ?height =b; ?? ?} ?? ? ?? ? int area() ?? ?{ ?? ??? ?printf("Parent class area:\n"); ?? ??? ?return 0; ?? ?} ?? ? ?? ? void sayHello() ?? ?{ ?? ??? ?printf("Shape..\n"); ?? ?} ?? ? ?? ?void bar() ?? ?{ ?? ??? ?printf("bar fun width:%d\n", width); ?? ?} ?? ? protected: ?? ?int width, height; };
void test2(Shape* shape) { ?? ?printf("\n----\n"); ?? ? ?? ?typedef void (*BAR_FUN)(void*); ?? ?typedef int (*AREA_FUN)(void*); ?? ?typedef void (*SAYHELLO_FUN)(void*); ?? ?typedef void (*CALL_FUN)(void*); ?? ?typedef void* ADDRESS; ?? ? ?? ?BAR_FUN bar_fun = (BAR_FUN)(&Shape::bar); ///bar成员函数为非虚函数 ?? ?bar_fun((void*) shape); ///调用bar函数,需要传入this指针就是shape ?? ? ?? ?///前面8个字节存放的是虚函数表,先将虚表首地址(二级指针)强制转换成void** 类型 ?? ?///虚表是二级指针,在首地址处 ?? ?ADDRESS* vtable_addr = *((ADDRESS**)(shape));///先将二级指针转换成一级指针,实现函数调用 ?? ?ADDRESS ptr = *(vtable_addr);///先获取到虚表的首地址 ?? ?AREA_FUN area_fun = (AREA_FUN)ptr; ///把虚函数area的首地址赋值给area_fun ?? ? ?? ?///vtable_addr + 1的原因是获取sayhello_fun函数地址 ?? ?SAYHELLO_FUN sayhello_fun = (SAYHELLO_FUN)*(vtable_addr+1); ?? ? ?? ?///vtable_addr + 2的原因是获取Call函数地址 ?? ?CALL_FUN ?call_fun = (CALL_FUN)*(vtable_addr+2); ?? ? ?? ?area_fun((void*)shape);?? ??? ??? ??? ?///传入this指针shape ?? ?sayhello_fun((void*)shape);?? ??? ??? ?///传入this指针shape ?? ?call_fun((void*)shape);?? ??? ??? ??? ?///传入this指针shape ?? ? ?? ?printf("\n----\n"); ?? ? }
int main() { ?? ?cout << sizeof(Shape) << endl;?? ??? ??? ??? ?///16个字节 ?? ?cout << sizeof(Triangle) << endl;?? ??? ??? ?///16个字节 ?? ?cout << sizeof(Rectangle) << endl;?? ??? ??? ?///16个字节 ?? ?cout << sizeof(Shape1) << endl;?? ??? ??? ??? ?///8个字节(没有加virtual关键字) ?? ?///说明写了virtual,C++编译器多分配了8个字节存放虚表,进行多肽, ?? ?///int width, height占了8个字节 ?? ? ?? ?///多肽 ?? ?Shape* shape = new Triangle(3, 4); ?? ?///test(shape); ?? ?test2(shape); ?? ?delete shape; ?? ? ?? ?///多肽 ?? ?shape = new Rectangle(5, 6); ?? ?///test(shape); ?? ?test2(shape); ?? ?delete shape; ?? ? ?? ?return 0; }
|