6

次のコードを検討してください。

#include <iostream>
using namespace std;

class Object
{
public:
    Object() {}

    void Print() const
    {
        cout << "const" << endl;
    }

    void Print()
    {
        cout << "mutable" << endl;
    }
};

void print_obj(const Object& obj)
{
    obj.Print();
}

int main()
{
    Object       obj1;
    const Object obj2;
    Object*const pobj1 = &obj1;
    
    print_obj(obj1);
    print_obj(obj2);
    
    obj1.Print();
    obj2.Print();
    
    pobj1->Print();
    
    return 0;
}

出力は

const
const
mutable
const
mutable

同じ名前の可変メソッドが多数ある場合、C++ はどのメソッドを呼び出すかをどのように決定するのでしょうか?

4

4 に答える 4

10
print_obj(obj1); 
print_obj(obj2); 

呼び出される関数は、渡されたオブジェクトのcv 修飾子( const/ ) に基づいて評価されます。関数のオーバーロードの解決中に cv 修飾子volatileが考慮されることに注意してください。 渡されたオブジェクトがの場合、引数を受け取る関数が選択されます。渡されたオブジェクトが非定数の場合、非定数の引数を受け取る関数が選択されます。
constconst


obj1.Print();   
obj2.Print();   
pobj1->Print();

オブジェクトがconstcallconstメンバー関数のみの場合、呼び出すことができます。
オブジェクトが非定数の場合、非定数バージョンがバージョンよりも優先されconstます。

ルールは規格によって明確に指定されています。

参照:
C++03 標準:
§13.3.1 候補関数と引数リスト:

非静的メンバー関数の場合、暗黙的なオブジェクト パラメーターの型は「cv への参照X」です。ここXで、 は関数がメンバーであるクラスであり、cv はメンバー関数宣言の cv 修飾です。[例: class の const メンバー関数のX場合、余分なパラメーターは「 const への参照」型を持つと見なされますX。]

したがって、オブジェクトが の場合、コンパイラは、の const バージョンである constへの型参照constの暗黙的なオブジェクト パラメーターを持つメンバー関数のバージョンを選択します。ObjectPrint()

于 2012-09-13T04:24:36.337 に答える
3

すべての関数のオーバーロードが同じように機能します。

オーバーロードのメンバー関数を検討する場合、暗黙的thisなパラメーターが含まれます。関数が宣言されている場合constthisパラメータはconst Object *です。関数がそうでないconst場合、thisパラメータはObject *です。const修飾子は関数のオーバーロード規則に影響するため、これは、関数のconst性質も関数のオーバーロード規則に影響することを意味します。

あなたの特定の例では、は を取ると宣言されているため、print_obj(obj1)印刷されます。つまり、常に のバージョンを呼び出します。と同じこと。constprint_obj()const Object&constPrint()print_obj(obj2)

obj1.Print()は is notであるmutableため出力されます。したがって、非バージョンのの方がより適切に一致し、関数オーバーロードの解決のために選択されます。obj1constconstPrint()

obj2.Print()is が出力constされるため、 のバージョンが適切な唯一の関数オーバーロードです。obj2constconstPrint()

pobj1->Print()は非値であるため出力されるため、非mutableバージョンのが関数オーバーロードの解決に選択されます。*pboj1constconstPrint()

それについて考える最も簡単な方法は、単に

void Print(Object &obj);
void Print(const Object &obj);
于 2012-09-13T04:25:39.957 に答える
1

通常のオブジェクトの場合、非constバージョンが利用可能な場合、非constバージョンが選択されることに注意してください。それ以外の場合は、constバージョンが選択されます。以下は分析です。

print_obj(obj1); // print_obj() receives const argument, so `const` is chosen
print_obj(obj2); // same as above

obj1.Print();  // obj1 is not const, so non-const version is chosen
obj2.Print();  // obj2 is const, so must choose const version

pobj1->Print(); // pobj1 is a const pointer pointing to non-const object, so non-const version is chosen
于 2012-09-13T04:29:12.677 に答える
-2

両方が可能であれば、非 const よりも const メソッドを優先します。

ところで、揮発性でも同じように機能します。

于 2012-09-13T04:24:04.783 に答える