///从网上抄来的,做了点修改,能正确运行出来而已
#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;
}