C++ 重载、覆盖和隐藏

1.重载

      所谓函数重载是指同一个函数名可以对应着多个函数的实现。例如,可以给函数名add()定义多个函数实现,该函数的功能是求和,即求两个操作数的和。其中,一个函数实现是求两个int型数之和,另一个实现是求两个浮点型数之和,再一个实现是求两个复数的和。每种实现对应着一个函数体,这些函数的名字相同,但是函数的参数的类型不同。这就是函数重载的概念。函数重载在类和对象的应用尤其重要。

      函数重载要求编译器能够唯一地确定调用一个函数时应执行哪个函数代码,即采用哪个函数实现。确定函数实现时,要求从函数参数的个数和类型上来区分。这就是说,进行函数重载时,要求同名函数在参数个数上不同,或者参数类型上不同。否则,将无法实现重载。

这里需要说明一下:重载仅在一个类下的函数之间产生

 代码示例:

#include <iostream>
#include <cstdlib>

using namespace std;

class OverLoad
{
      public:
             int add(int x,int y);
             int add(int x,int y,int z);
};

int OverLoad::add(int x,int y)
{
    return x+y;
}

int OverLoad::add(int x,int y,int z)
{
      int temp=x+y;
      return temp+z;
}

int main()
{
    OverLoad ad;
    int ri = ad.add(9,4);
    int rd = ad.add(9,4,6);
    
    cout<<"int2 add result:"<<ri<<endl;
    cout<<"int3 add result:"<<rd<<endl;
    
    system("pause");
    return 0;
}
//输出13和19 

 

2.覆盖
与重载不同,覆盖通过虚函数(virtual)机制重写父类的函数,即要与父类相应的函数类型,参数类型保持一致,注意覆盖函数不能声明为static,在下面的代码示例中,fun之间实现了重载,fun同在一个Base类里面,fun2v之间实现了覆盖,利用虚函数机制(virtual).

代码示例:

#include <iostream>
#include <cstdlib>

using namespace std;
 
class Base
{
      public:
             void fun(int x){ cout << "Base::f(int) " << x << endl; }
             void fun(float x){ cout << "Base::f(float) " << x << endl; }
             virtual void fun2v(void){ cout << "Base::f(void)" << endl;}
};

class Derived : public Base
{
      public:
             void fun2v(void){ cout << "Derived::f(void)" << endl;}
};


int main()
{
    Derived d;
    Base *pb = &d;
    pb->fun(100); 
    
    pb->fun(100.00f); 
    pb->fun2v();
    
    system("pause");
}
//输出:
//Base::f(int) 100
//Base::f(float) 100
//Derived::f(void)


3.隐藏

隐藏与前两点相似,但是与重载不同的是隐藏发生父类与派生类函数之间,即跨类,与覆盖不同的是派生类类函数与父类函数的函数类型可以不一致,也可以没有virtual关键字,当然这都是在函数名相同的前提下

所以隐藏有两种实现的形式

1).派生类的函数与基类的函数同名,但是参数不同 此时virtual可有可无(不是重载) 例如下面函数 fun3v

2).派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字(不是覆盖) 例如下面函数fun4v

代码示例:

#include <iostream>
#include <cstdlib>

using namespace std;
 
class Base
{
      public:
             void fun(int x){ cout << "Base::f(int) " << x << endl; }  
             void fun(float x){ cout << "Base::f(float) " << x << endl; }
             
             virtual void fun2v(void){ cout << "Base::f(void) 2verson" << endl;}
             
             virtual void fun3v(int x){ cout << "Base::f(int) 3version " << x << endl; }             //virtual可有可无 
             
             void fun4v(int x) { cout << "Base::f(int) 4version " << x << endl; }
};

class Derived : public Base
{
      public:
             void fun2v(void){ cout << "Derived::f(void) 2version" << endl;}                          //覆盖 
             void fun3v(int x,int y){ cout << "Derived::f(int,int) 3version" << x << y << endl; }      //隐藏第1种形式 
             void fun4v(int x){ cout << "Derived::f(int) 4version" << endl;}                           //隐藏第2种形式
};


int main()
{
    Derived d;
    Base *pb = &d;
    Derived *pd = &d;
    
    pb->fun(100); 
    
    pb->fun(100.00f); 
    pb->fun2v();
    
    cout<<"------------------------------"<<endl;
    
    pd->fun3v(3,4);
    pd->fun4v(1);
    
    system("pause");
}
//输出:
//Base::f(int) 100
//Base::f(float) 100
//Derived::f(void) 2version
//-------------------------------
//Derived::f(int,int) 3version34
//Derived::f(int) 4version

 

4.重载、覆盖和隐藏区别

综上它们之间的区别可以总结如下:(参考网络流行的说法)

  • 成员函数被重载的特征

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual 关键字可有可无。

  • 覆盖是指派生类函数覆盖基类函数,特征是

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual 关键字。

  • “隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

 

 

 

 

 

 

posted on 2012-07-24 20:43  as_  阅读(765)  评论(0编辑  收藏  举报

导航