C++的多态性来源有两类:
一类是由于静态联编技术实现的编译时的动态性,通过函数重载和模板实现;编译时就知道运行时 要采取的动作,所以效率较高。
一类是由于动态联编技术实现的运行时的动态性,通过虚函数实现;运行时动态决定该采取的动作,所以效率较低。
本文主要关于C++的虚函数部分。
首先,基类指针可以指向派生类对象。当基类中的某个函数,如:show()函数在派生类中重写了一个show()函数的话,那么,我们用这个基类指针调用show()函数时,程序会采取什么动作呢?我们还是先做一个实验:
//dyn.h
#ifndef DYN_H
#define DYN_H
namespace dyn{
class Base{
public:
void show();<span style="white-space:pre"> </span>//<------------------------------------virtual void show();
};
class B1 :public Base{
public:
void show();
};
class B2 :public Base{
public:
void show();
};
}
#endif
//dyn.cpp
#include "dyn.h"
#include <iostream>
using std::cout;
using std::endl;
using dyn::Base;
using dyn::B1;
using dyn::B2;
void Base::show(){
cout << "class Base" << endl;
}
void B1::show(){
cout << "class B1" << endl;
}
void B2::show(){
cout << "class B2" << endl;
}
#include "dyn.h"
using dyn::Base;
using dyn::B1;
using dyn::B2;
int main(){
Base b, *pb;
B1 b1, *pb1;
B2 b2, *pb2;
pb = &b1;
pb->show();
return 0;
}
运行结果显示,程序执行了Base类的show(),显然这并不符合我们的要求,我们希望即使我们用基类指针指向派生类对象,我们调用函数时会优先调用我们派生类的改造过的函数。
C++提供了虚基类这个概念来解决这个问题。只需要在基类成员函数前面加上virtual关键字即可。
-----------------------------------------------------------------------------------------------------------------------------------------------
在java中,就要简单得多(O(∩_∩)O哈哈~,很喜欢java的设计啊)
public class Father {
public void show(){
System.out.println("i am father");
}
}
public class Son extends Father {
public void show(){
System.out.println("i am son");
}
}
public class t {
public static void main(String[] args){
Father f = new Son();
f.show();<span style="white-space:pre"> </span>//<---------------------------------i am son
}
}