C++的隐藏/覆盖

来源:互联网 发布:06年nba总决赛数据 编辑:程序博客网 时间:2024/04/30 03:27


1. 重载、覆盖与隐藏

1).重载:成员函数具有以下的特征时发生"重载"

A.相同的范围(同一个类中)

B.函数的名字相同

C.参数类型不同(不能进行隐式类型转换)

D.Virtual关键字可有可无

2).覆盖(也叫"继承"):指派生类函数覆盖基类函数,特征是:

A.不同的范围(分别位于基类与派生类中)

B.函数名字相同

C.参数相同

D.基类函数必须有virtual关键字

3).隐藏:是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

A.如果派生类的函数与基类的函数同名,但是参数不同,此时不论有无virtual关键字,基类的函数都将被隐藏,注意别与重载混淆)

B.如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时基类的函数被隐藏(注意别与覆盖混淆)

-------------------------------------------

覆盖:函数名字相同;参数相同;基类函数必须有virtual函数。
隐藏的定义是派生类的函数屏蔽了其同名的基类函数。
隐藏规则:
如果派生类的函数与基类函数同名,但是参数不同,无论是否有virtual关键字,基类的函数将被隐藏。 
如果派生类的函数与基类函数同名,而且参数相同,但是基类的函数没有virtual关键字,则基类的函数被隐藏。

基类:
class Base  
{
public:
 Base();
 virtual ~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:
 Derived();
 virtual ~Derived();
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;
 }
};

 Derived  d;
 Base *pb = &d;
 Derived *pd = &d;
 
 pb->f(3.14f); // Derived f(float)3.14 调用派生类函数
 pd->f(3.14f); // Derived f(float)3.14 调用派生类函数
 
 pb->g(3.14f); // Base g(float)3.14 (!) 调用基类函数
 pd->g(3.14f); // Derived g(int)3       调用派生类函数  
 
 pb->h(3.14f); // Base h(float)3.14 (!) 调用基类函数
 pd->h(3.14f); // Derived h(float)3.14  调用派生类函数

 

在这个例子中,
(1)函数Derived::f(float)覆盖了Base::f(float)。
(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。
(3)函数Derived::h(float)隐藏了Base::h(float),而不是覆盖。


覆盖与隐藏的区域在于参数与virtual的异同,若参数不同,则为覆盖,若参数相同,再看是否有virtual关键字,若有,则为覆盖,否则隐藏。

Java中似乎没有隐藏规则,至少俺没发现。
如果参数相同,则覆盖,参数不同,则派生类继承这个函数。

class Base {
 public void f(float x) {
  System.out.println("Base f(float)" + x);
 }
 public void f(int x) {
  System.out.println("Base f(int)" + x);
 }
}
class Derived extends Base {
 public void f(int x) {
  System.out.println("Derived f(int)" + x);
 }
}

  Derived pd=new Derived();
  Base pb=pd;
  pb.f(3.14f); //Base f(float)3.14 调用基类函数
  pd.f(3.14f); //Base f(float)3.14 调用基类函数
  pb.f(3);     //Derived f(int)3 覆盖,调用派生类函数
  pd.f(3);     //Derived f(int)3 覆盖,调用派生类函数


看来用C++时要多多小心才是。


原创粉丝点击