重载主要是发生在同一个类中,派生类中的函数方法与继承过来的基类的方法也可以发生重载,重载函数特点为:
1. 函数名相同;
2. 函数参数列表(包括参数类型,参数个数,参数顺序)不同。不用关心返回值类型是否相同、是否有virtual修饰符等。
覆盖是发生在基类和派生类之间,指派生类的函数覆盖基类的函数,覆盖函数的特点为:
1.基类中该函数要有virtual修饰
2.函数名、返回值、参数列表都必须相同
隐藏也是发生在父子类之间,指基类的函数被派生类的隐藏,隐藏发生的特点为:
1.派生类与基类的函数名要相同
2.基类函数不用virtual修饰,派生类与基类函数参数列表相同 或者 当派生类与基类函数列表不同时,无论是否用virtual修饰
先举个小例子:
#include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; class SBase { public: SBase(){} ~SBase(){} int f1(int a){printf("Base f1\n");return 0;} virtual int g1(int a){printf("Base g1 int\n");return 0;} int g1(short a){printf("Base g1 short\n");return 0;} }; class SDerived:public SBase { public: SDerived(){} ~SDerived(){} int f1(int a){printf("Derived f1\n");return 0;} int g1(int a){printf("Derived g1 int\n");return 0;} virtual int g1(short a){printf("Derived g1 short");return 0;} }; int main() { SBase* p1=new SDerived; (*p1).g1(short(1)); p1->g1(1); ((SBase)(*p1)).f1(1); p1->f1(1); (*(SDerived*)p1).f1(1); return 0; }
结果:
Base g1 short //隐藏
Derived g1 int //覆盖
Base f1 //隐藏
Base f1 //隐藏
Derived f1 //隐藏
参考网址:
http://blog.csdn.net/lenotang/article/details/2681525
http://soft.chinabyte.com/database/348/12279348.shtml
另外一个虚函数默认参数的例子:
#include<iostream> using namespace std; enum COLOR{RED,GREEN,COLORSIZE}; std::string colorstr[COLORSIZE]={"RED","GREEN"}; class Shape{ public: virtual void draw(COLOR color=RED)const{ std::cout<<"Shape:"<<colorstr[color]<<endl; } }; class Circle:public Shape{ public: virtual void draw(COLOR color=GREEN)const{ std::cout<<"Circle:"<<colorstr[color]<<endl; } }; int main() { Shape* ps=new Circle(); ps->draw(); delete ps; return 0; }
以上结果是Circle:RED
原因是虚函数是动态绑定而缺省参数值是静态绑定的。
在编译阶段,编译器并不知道ps指向的是基类还是派生类,默认当成的是Shape,所以用基类的默认参数。
注意:如果只有派生类有默认参数,那么编译器认为这两个函数是不一样的。
参考网址:
http://blog.csdn.net/airekans/article/details/6881755