为了理解多态性,做了一个小实验,用事实说话~代码如下:
#include <iostream>
#include <stdlib.h>
using namespace std;
class Cup
{
public:
virtual void color() = 0;
};
class TeaCup
{
public:
virtual void color()
{
cout << "have a tea,change a mood " << endl;
}
};
class Fathor
{
public:
virtual void vf1()
{
cout << "fathor: vf1 " << endl;
}
virtual void vf2(float x)
{
cout << "fathor: vf2 : " << x << endl;
}
virtual void vf3(float x)
{
cout << "fathor: vf3 : " << x << endl;
}
void f1()
{
cout << "fathor: f1" << endl;
}
void f2(float x)
{
cout << "fathor: f2 : " << x << endl;
}
void f3(float x)
{
cout << "fathor: f3 : " << x << endl;
}
void f4(float x)
{
cout << "fathor f4 : " << x << endl;
}
};
class Son : public Fathor
{
public :
virtual void vf1()
{
cout << "son: vf1" << endl;
}
virtual void vf2(float x)
{
cout << "son: vf2 : " << x << endl;
}
virtual void vf3(int x)
{
cout << "son : vf3 : " << x << endl;
}
void f1()
{
cout << "son : f1" << endl;
}
void f2(float x)
{
cout << "son: f2 : " <<x<< endl;
}
void f3(int x)
{
cout << "son : f3 : " << x << endl;
}
virtual void f4(float x)
{
cout << "son : f4 : " << x << endl;
}
};
int main()
{
Fathor fathor;
Son son;
TeaCup teacup;
Fathor *fp = &fathor;
Son *sp = &son;
TeaCup *tp = &teacup;
cout << "the address for the fathor object :" << fp << endl;
fp->vf1();// for a try
fp = &son;
cout << "the address for the son object : " << fp <<endl;
// no parameter
fp->vf1();
sp->vf1();
fp->f1();
sp->f1();
// the same parameter
fp->vf2(2014.0801);
sp->vf2(2014.0801);
fp->f2(2014.0801);
sp->f2(2014.0801);
//the different types of parameter
cout << "different parameter types : No overloading" << endl;
fp->vf3(2014.0801);
sp->vf3(2014.0801);
fp->f3(2014.0801);
sp->f3(2014.0801);
cout << "different function types : No override/ rewritting" << endl;
// the fathor class has no virtual
fp->f4(2014.0801);
sp->f4(2014.0801);
// to see the son of the abstract class
tp->color();
system("PAUSE");
return 0;
}
运行结果:
结果分析:
1.基类指针,指向基类对象,调用基类本身的函数
fp->vf1();// for a try
2. no parameter
fp->vf1(); // OUTPURT son: vf1
分析: 基类指针,指向子类对象,体现多态性。指向vf1(虚函数),通过虚函数列表找到函数地址,对象不同时,虚函数地址不同。
因此此时找到了子类对象的虚函数地址。
sp->vf1();//OUTPUT son: vf1
分析:子类指针,指向子类对象,调用子类本身的函数。
fp->f1();//OUTPUT fathor:f1
分析:基类指针,指向子类对象,体现多态性。指向f1(固定偏移量的函数),偏移量由指针类型决定,因而此时指向基类的f1()。
sp->f1();//OUTPUT son :f1
分析:子类指针,指向子类对象,调用子类本身的函数。
3. the same parameter
fp->vf2(2014.0801); // OUTPUT: son : vf2:2014.08
分析:此时指向子类对象的虚函数vf2
sp->vf2(2014.0801); // OUTPUT: son : vf2 2014.08
分析:调用子类本身的函数
fp->f2(2014.0801); //OUTPUT fathor : f2 :2014.08
分析:不是虚函数的成员函数,在参数指向基类的f2()
sp->f2(2014.0801); //OUTPUT son : f2 : 2014.08
分析:指向子类的f2()
4.the different types of parameter
fp->vf3(2014.0801); // OUTPUT: fathor vf3 :2014.08,
分析:函数同名,但是参数类型不同时,不管有无vitrual,都是根据指针类型进行判断的
sp->vf3(2014.0801); // OUTPUT:son vf3 :2014
分析:sp为子类指针,即调用子类对象的函数
fp->f3(2014.0801); //OYUTPUT:faothor f3 :2014.08
分析:fp为父类指针,即调用父类对像的函数
sp->f3(2014.0801); //OUTPUT:son f3 :2014
分析:根据隐藏规则,派生类的函数与基类函数同名,但是参数不同时,不管有没有virtual,都将基类的函数隐藏,不是重载。
5.the fathor class has no virtual
fp->f4(2014.0801); //OUTPUT:fathor f4:2014.08
分析:函数同名,但是基类没有virtual ,还是根据指针类型进行判断
sp->f4(2014.0801);//OUTPUT: son f4:2014.08
分析:根据隐藏规则,派生累的函数与积累函数同名,参数也相同,但是基类没有virtual时,也将基类函数隐藏,不是覆盖。