比如看下面的代码:
class Animal { public: //虚函数 virtual void speak() { cout << "动物在说话" << endl; } virtual void eat(int a ) { cout << "动物在吃饭" << endl; } }; class Cat :public Animal { public: void speak() { cout << "小猫在说话" << endl; } void eat(int a) { cout << "小猫在吃饭" << endl; } }; class Dog :public Animal { public: void speak() { cout << "小狗在说话" << endl; } };
这两个类实现集成关系,简单来说就是 Animal是父类,Cat是子类,通过父类引用调用子类函数,这就是多态(字面意思就是一个对象多个状态),这样就 符合** 高内聚低耦合** 的设计原则,更容易 后期维护与修改
说了这么多,那么多态到底怎么实现呢?
正如下所示:
void doSpeak(Animal & animal) //Animal & animal = cat; { animal.speak(); } void test01() { Cat cat; doSpeak(cat); Dog dog; doSpeak(dog); }
如此方能满足实现多态的三个条件:
那么虚函数到底是怎么工作的呢?
void test02() { Animal * animal = new Cat; ((void(*)()) (*(int *)*(int *)animal)) (); typedef void( __stdcall *FUNPOINT)(int); (FUNPOINT (*((int*)*(int*)animal + 1)))(10); }
Animal * animal = new Cat;
就是animal->speak();
((void(*)()) (*(int *)*(int *)animal)) ();
这里 *(int *)animal
解引用到虚函数表中,先将animal类型的指针强转为int *
,然后解引用得到int类型的值放到虚函数表中,然后偏移相应位置指向speak()
((void(*)()) (*(int *)*(int *)animal)) ();
调用猫说话,因为C/C++默认调用惯例 __cdecl
,而用下列调用时 是__stdcall
typedef void( __stdcall *FUNPOINT)(int); (FUNPOINT (*((int*)*(int*)animal + 1)))(10);