簡體   English   中英

在函數聲明末尾使用“ const”重載

[英]Overloading with “const” at end of function declaration

我有3次嘗試重載函數“ begin()”

class Test
{
public:

    //case 1: compiler error
    int begin();
    const int begin();

    //case 2:compiler warning: type qualifiers ignored on function return type
    int begin();
    const int begin() const;

    //case 3: ok
    int begin();
    int begin() const;
};

對於成功構建的兩種情況,編譯器如何選擇為begin()調用的重載?

成員函數有一個隱式參數,它是類本身的實例。 因此,您可以認為您的功能看起來像這樣:

// 1) compile-error as const-qualifications on return doesn't distinguish
//    the functions - you cannot overload on return type
int begin(Test& );
const int begin(Test& );

// 2)
int begin(Test& );
const int begin(const Test& );

// 3)
int begin(Test& );
int begin(const Test& );

在第二和第三種情況下, const上的const限定等同於隱式參數是對const的引用。 所以當你有類似的東西:

Test{}.begin();

該調用begin()使用對非const Test的引用作為隱式第一個參數。 begin()兩個重載都是可行的,都不需要進行轉換,因此最好使用cv限定的引用最少,即非const限定的函數。

相反,當您擁有:

(const Test{}).begin();

我們在調用begin()時引用了const Test 因此,非const限定的函數不是可行的候選對象(您不能將const-ref傳遞給期望非const-ref的函數),因此最佳可行的候選對象是唯一可行的候選對象: int begin() const

情況1含糊,原因是返回類型不參與重載解析,情況2與情況3等效,因為在返回類型中const被丟棄在情況3中:

const Test t1;
t1.begin() // calls int begin() const;
Test t2;
t2.begin() // calls int begin();

來自cppreference.com

可以使用const,volatile或const volatile限定符聲明非靜態成員函數(此限定符出現在函數聲明中的函數名稱之后)。 具有不同cv資格的函數具有不同的類型,因此可能會彼此過載。 在cv限定函數的主體中,this指針是cv限定的,例如,在const成員函數中,通常可以僅調用其他const成員函數。 (如果應用const_cast或通過不涉及此函數的訪問路徑,仍可以調用非const成員函數。)

需要記住的一些規則:

  1. 您不能僅基於返回類型重載方法。 這會導致您的案例1中出現錯誤。

  2. 當按值返回時,const限定符是多余的。 在您的情況2中,編譯器會警告您有關此問題。

  3. 該類的每個非靜態方法都有一個隱式參數。 在方法調用時,將其分配給在其上調用方法的實例。 方法聲明末尾的const關鍵字(在方法主體之前)適用於此隱式參數。 從本質上講,該函數的主體不會修改實例的狀態(數據成員)。 如果在const實例上調用該方法,則需要定義const方法。 此外,您可以僅基於方法是否為常量這一事實來重載該方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM