C++:Name Lookup & Best Match

2228 ワード

名前の検索
変数またはオブジェクトが現れるたびに、コンパイラは名前検索(name lookup)を行い、この変数またはオブジェクトの具体的な属性を確認します.一般的には、プログラムは変数が現れる場所から上へ検索し、各レベルの役割ドメインを内向的に外へ検索してグローバル役割ドメインに直行し、同名の変数宣言を見つけると停止し、最終的に見つからないとエラーを報告します.
#include 
using namespace std;

int a = 0;

int main() {
    string a = "1";
    cout << a << endl; //  main       a   ,      ,   string   “1”
    return 0;
}

名前検索はまた、役割ドメイン限定子::の影響を受け、変数の前に役割ドメイン限定が発生すると、限定された役割ドメイン内からグローバル検索が行われ、他の場所は検索されません.::以前に役割ドメイン名が表示されなかった場合、グローバル役割ドメインで検索されます.
#include 
using namespace std;

int a = 0;

int main() {
    string a = "1";
    cout << ::a << endl; //   a           ,         a int    ,    0
    return 0;
}

また、同じ名前の宣言が見つかった後に検索が停止するため、関数マッチングは名前検索の後に表示されます.
#include 
using namespace std;

void print() { cout << "1" << endl; }

int main() {
    int print;
    print(); //     print(),         ,       int   print  ,
             //          ,                 
    return 0;
}

名前を隠す
上記の例から分かるように、アクセス制限子を使用しない場合、内層役割ドメインの変数は外層役割ドメインの同名変数、すなわち名前非表示が発生する.名前の非表示はクラスの継承プロセスでも発生します.サブクラスが親と同じ名前のメンバーを定義すると、親から継承されたメンバーが非表示になります.名前の非表示は特性ではありません.逆に、名前の非表示はプログラムの作成を難しくします.名前の隠すことを避けるために、良い命名習慣を身につけなければなりません.
さいてきマッチング
関数呼び出し時に、まず関数の名前を検索し、同じ名前の関数が見つかりました(ネーミング競合が発生しないと仮定)では、コンパイラは検索を停止するのではなく、現在の役割ドメインのすべてのリロード関数を見つけ続け、最適な一致規則に基づいて実際に呼び出された関数を決定します.異なる役割ドメインの同名関数はリロードと見なされません.最も直感的な例は、クラス内の関数とクラス外の同名関数はリロードを形成しません.
名前の検索が完了し、コンパイルエラーが存在しない場合、コンパイラは呼び出しと最もよく一致する関数の決定を開始します.最適マッチングの原則も簡単で,実パラメータタイプがパラメータタイプに近いほどマッチングが良好である.
void print(int a) { cout << "int" << endl; }

void print(double a) { cout << "double" << endl; }

print(1); // 1 int  , print int          ,     “int”

しかし、呼び出しと一致する複数の関数が同時に存在する場合、コンパイラはエラーを報告します.コンパイラは、二義的な呼び出しの存在を許可しません.
void print(int a, int b, int c) { cout << "int" << endl; }

void print(double a, double b, double c) { cout << "double" << endl; }

print(1, 1.0, 1); //