重载(overload)、覆盖(override)、隐藏(hide)的区别 (转)

转自http://blog.csdn.net/yanjun_1982/archive/2005/09/02/470405.aspx

 

 这三个概念都是与OO中的多态有关系的。如果单是区别重载与覆盖这两个概念是比较容易的,但是隐藏这一概念却使问题变得有点复杂了,下面说说它们的区别吧。

       重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。

 

       覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。

 

       隐藏是指派生类中的函数把基类中相同名字的函数屏蔽掉了。

如果派生类函数与基类函数同名,但参数不同,无论基类函数前是否有virtual修饰,基类函数被隐.
如果派生类函数与基类函数同名,参数也相同,但是基类函数前无virtual修饰,基类函数被隐藏。

 

复制代码
#include <iostream.h>  

    class Base  

{  

public:  

    virtual void f(float x){ cout << "Base::f(float) " << x << endl; }  

void g(float x){ cout << "Base::g(float) " << x << endl; } 

            void h(float x){ cout << "Base::h(float) " << x << endl; }  

};  

    class Derived : public Base 

{  

public:  

    virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }  

void g(int x){ cout << "Derived::g(int) " << x << endl; } 

            void h(float x){ cout << "Derived::h(float) " << x << endl; } 

};  
复制代码

 

看出什么了吗?下面说明一下:

(1)函数Derived::f(float)覆盖了Base::f(float)。  

(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。  

(3)函数Derived::h(float)隐藏了Base::h(float),而不是覆盖。

复制代码
void main(void)  

{  

Derived  d;  

Base *pb = &d;  

Derived *pd = &d; 
 

// Good : behavior depends solely on type of the object  

pb->f(3.14f); // Derived::f(float) 3.14  

pd->f(3.14f); // Derived::f(float) 3.14  


// Bad : behavior depends on type of the pointer  

pb->g(3.14f); // Base::g(float) 3.14  

pd->g(3.14f); // Derived::g(int) 3        (surprise!)  


// Bad : behavior depends on type of the pointer  

pb->h(3.14f); // Base::h(float) 3.14      (surprise!)  

pd->h(3.14f); // Derived::h(float) 3.14  

} 
复制代码

在第一种调用中,函数的行为取决于指针所指向的对象。在第二第三种调用中,函数的行为取决于指针的类型。所以说,隐藏破坏了面向对象编程中多态这一特性,会使得OOP人员产生混乱。  

如果pd想要调用Base::g(float),可以用pd->Base::g(3.14f),增加基类作用域的形式来实现。

 

 

当基类定于多个同名函数的时候,只要派生类中出现了一个或多个相应的同名函数,这个时候会隐藏基类所有的相应同名函数

复制代码
#include <iostream>
using namespace std;

class Base {
 public:
  void Fun() 
  {   
    cout << "Func" << endl;
  }
  
  void Fun(int c ) 
  {
   cout << "Fun" << c << endl;
  }
};

class Dervied : public Base {
 public:
  void Fun()
  {
    cout << "Func Dervied" << endl;
  }
};

int main() 
{
  Dervied d;
  d.Fun();
  d.Fun(2);
  return 0;
}

error: no matching function for call to 'Dervied::Fun(int)'
note: candidates are: void Dervied::Fun()
复制代码

从上面的列子可以看出,虽然派生类中只定义了一个 与基类同名的函数,但是它隐藏了基类所有的同名函数。所以从中可以看出,隐藏和名称相关和其他没有关系,只要派生类中定义了同名函数,那在基类中所有的同名函数都会被隐藏,与参数和个数无关。

当覆盖(重写)遇到隐藏
当我们覆盖(重写)基类的虚函数的时候也会发生隐藏,就像下面的列子我们从基类继承了俩个函数,我们只重写了一个函数,但是剩下没有被重写的基类函数我们也无法使用了,它被隐藏了起来

复制代码
#include <iostream>
using namespace std;

class Base {
 public:
  virtual void Fun() 
  {   
    cout << "Func" << endl;
  }
  
  void Fun(int c ) 
  {
   cout << "Fun" << c << endl;
  }
};

class Dervied : public Base {
 public:
  void Fun(char c)
  {
    cout << "Func Dervied" << endl;
  }
};

int main() 
{
  Dervied d;
  d.Fun();
  d.Fun(2);
  return 0;
}
 In function 'int main()':
 error: no matching function for call to 'Dervied::Fun()'
 note: candidates are: void Dervied::Fun(char)
复制代码

 

posted @   鸭子船长  阅读(253)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2016-03-25 android中Camera setDisplayOrientation使用
点击右上角即可分享
微信分享提示