オーバーロード(overload)、オーバーライド(override)、非表示(hide)の違い


オーバーロード(overload)、オーバーライド(override)、非表示(hide).初期のC++書籍では、翻訳可能な人は専門用語に慣れていない(彼らのせいにもできない.彼らはコンピュータのプログラミングをしているわけではない.彼らは英語を専門としている).
(overload)とオーバーライド(override)が間違っています!
まず、いくつかのコードとそのコンパイル結果を見てみましょう.
例1:
#include "stdafx.h"
  #include <iostream.h>

  class CB
  {
  public:
     void f(int)
     {
        cout << "CB::f(int)" << endl;
     }

  };


  class CD : public CB
  {
  public:
     void f(int,int)
     {
        cout << "CD::f(int,int)" << endl;
     }

     void test()
     {
       f(1);
     }
  };

 int main(int argc, char* argv[])
 {
    return 0;
 }

コンパイルしてみました
error C2660: 'f' : function does not take 1 parameters
結論:クラスCDというドメインでは,f(int)のような関数はなく,ベースクラスにおけるvoid f(int)が隠されている.
派生CDにおけるメンバ関数void f(int,int)の宣言をベースクラスと同様,すなわちf(int)に変更すると,ベースクラスにおけるvoid f(int)は同様に上書きされ,このときコンパイルはエラーなく,関数においてtestが呼び出すのはCDにおけるf(int)である.
したがって、ベースクラスのいくつかの関数では、virtralキーワードがなく、関数名がf(パラメータが何であるかは関係ありません)である場合、派生クラスCDにfメンバー関数が宣言されている場合、クラスCDドメインでは、ベースクラスのすべての
それらのfはすべて隠されている.
もしあなたが焦って、何が隠れているのか知りたいなら、文章の最後の簡単な説明を見てください.でも、一歩一歩見ていくことをお勧めします.私たちがさっき言ったのはvirtualがない場合ですが、virtualがある場合は??
例2:
<pre name="code" class="cpp">#include "stdafx.h"
#include <iostream.h>

class CB
{
public:
   virtual void f(int)
   {
      cout << "CB::f(int)" << endl;
   }

};


class CD : public CB
{
public:
   void f(int)
   {
      cout << "CD::f(int)" << endl;
   }

};

int main(int argc, char* argv[])
{
  return 0;
}
 这么写当然是没问题了,在这里我不多费口舌了,这是很简单的,多态,虚函数,然后什么指向基类的指针指向派生类对象阿,通过引用调用虚函数阿什么的,属性多的很咯,什么??你不明白??随便找本C++的书,对会讲多态和虚函数机制的哦!!  这种情况我们叫覆盖(override)!覆盖指的是派生类的虚拟函数覆盖了基类的同名且参数相同的函数!  在这里,我要强调的是,这种覆盖,要满足两个条件 (a)有virtual关键字,在基类中函数声明的时候加上就可以了 (b)基类CB中的函数和派生类CD中的函数要一模一样,什么叫一模一样,函数名,参数,返回类型三个条件。  有人可能会对(b)中的说法质疑,说返回类型也要一样??  是,覆盖的话必须一样,我试了试,如果在基类中,把f的声明改成virtual int f(int),编译出错了  error C2555: 'CD::f' : overriding virtual function differs from 'CB::f' only by return type or calling convention  所以,覆盖的话,必须要满足上述的(a)(b)条件  那么如果基类CB中的函数f有关键字virtual ,但是参数和派生类CD中的函数f参数不一样呢,实例三: 
  
  
 
 #include "stdafx.h"
#include <iostream.h>

class CB
{
 public:
    virtual  void f(int)
   {
      cout << "CB::f(int)" << endl;
   }

}
;


class CD : public CB
{
public:
    void f(int,int)
   {
     cout << "CD::f(int,int)" << endl;
   }

   void test()
   {
      f(1);
   }
}
;

int main(int argc, char* argv[])
{
 return 0;
}

コンパイルエラーが発生しました.
error C2660: 'f' : function does not take 1 parameters
あれ?見覚えのある間違い??はい、インスタンス1の場合と同じですよ.結論もベースクラスの関数が隠されています.
上の3つの例を通して,簡単な結論を出した.
ベースクラスの関数と派生クラスの2つの名前の同じ関数f
次の2つの条件を満たす
(a)ベースクラスで関数宣言時にvirtualキーワードがある
(b)ベースクラスCBの関数は派生クラスCDの関数とそっくりであり,関数名,パラメータ,戻りタイプは同じである.
これがオーバーライド(override)と呼ばれ、これが虚関数であり、多態の性質である.
では、他の状況は??名前が同じであれば、上記の条件を満たさないのは、隠すことです.
次に、最も重要な点についてお話しします.多くの人は、ベースクラスCBのf(int)が継承され、CDのf(int,int)が派生クラスCDに再ロードされると考えています.例1で想像したように.
そうですか.まず、リロードの定義を見てみましょう.
リロード(overload):
1つのドメインでは、関数名は同じですが、関数パラメータは異なり、リロードの役割は同じ関数が異なる動作をするため、1つのドメインではない関数はリロードを構成できません.これはリロードの重要な特徴です.
1つのドメインでなければならないが,継承は明らかに2つのクラスにあるので,上記の考え方は成り立たないが,我々がテストした構造も同様であり,派生クラスのf(int,int)はベースクラスのf(int)を隠している.
したがって、同じ関数名の関数は、ベースクラスと派生クラスの関係が上書きまたは非表示になるしかありません.
文章の中で、私は重荷とカバーの定義をすべて出して、しかしずっと隠れた定義にあげていないで、最後に、私は彼を出して、この話はネット上のgoogleから来て、比較的に長くて、あなたは簡単に理解することができて、派生クラスのドメインの中で、ベースクラスの中のあの同名の関数が見えなくて、あるいは、あなたに引き継いでいないで、ほほほ、実例1のように.
  
非表示(hide):
派生クラスのメンバー関数がベースクラス関数を隠すメンバー関数を指す.クラスのメンバー関数を呼び出すと、コンパイラはクラスの継承チェーンに沿って関数の定義を逐次上検索し、見つかったら検索を停止するので、派生クラスとベースクラスが同じ名前(パラメータが同じかどうかにかかわらず)の関数を持つ場合、コンパイラは最終的に派生クラスで関数を選択します.この派生クラスのメンバー関数は、ベースクラスのメンバー関数を「非表示」にする、すなわち、コンパイラが関数の定義を上へ検索し続けることを阻止する.
c++リロードオーバーライド非表示の違いと実行方式メンバー関数がリロードされる特徴(1)同じ範囲(同じクラスにある);(2)関数名が同じ;(3)パラメータが異なる;(4)virtualキーワードがあってもなくてもよい.オーバーライドは生クラス関数がベースクラス関数数をオーバーライドすることを割り当て、特徴は(1)異なる範囲である(それぞれ派生クラスとベースクラスにある);(2)関数の名前が同じ;(3)パラメータが同じ;(4)ベースクラス関数にはvirtualキーワードが必要です.「非表示」は、生クラスを割り当てる関数が同名のベースクラス関数をマスクしていることです.ルールは次のとおりです.(1)派生クラスの関数がベースクラスの関数と同じ名前であるが、パラメータが異なる場合.この場合、virtualキーワードの有無にかかわらずベースクラスの関数は非表示になる(リロードと混同しないように注意).(2)派生クラスの関数がベースクラスの関数と同じ名前でパラメータも同じであるが、ベースクラスの関数にvirtualキーワードがない場合.この場合、ベースクラスの関数は非表示になる(オーバーライドと混同しないように注意)3つの場合の実行方法:1.リロード:パラメータ2を参照.非表示:何で呼び出すか3.オーバーライド:派生クラスを呼び出す