簡體   English   中英

調用 const 函數而不是它的非常量版本

[英]Calling a const function rather than its non-const version

為了我的目的,我試圖包裝類似於 Qt 的共享數據指針的東西,在測試時我發現當應該調用 const 函數時,它的非 const 版本被選擇了。

我正在使用 C++0x 選項進行編譯,這是一個最小的代碼:

struct Data {
    int x() const {
        return 1;
    }
};

template <class T>
struct container
{
    container() {
        ptr = new T();
    }


    T & operator*() {
        puts("non const data ptr");
        return *ptr;
    }

    T * operator->() {
        puts("non const data ptr");
        return ptr;
    }

    const T & operator*() const {
        puts("const data ptr");
        return *ptr;
    }

    const T * operator->() const {
        puts("const data ptr");
        return ptr;
    }

    T* ptr;
};

typedef container<Data> testType;

void testing() {
    testType test;
    test->x();
}

如您所見,Data.x 是一個 const 函數,因此被調用的運算符 -> 應該是 const 函數。 當我注釋掉非常量的時候,它編譯沒有錯誤,所以這是可能的。 然而我的終端打印:

“非常量數據ptr”

這是 GCC 錯誤(我有 4.5.2),還是我遺漏了什么?

如果您有兩個僅在const上不同的重載,則編譯器會根據*this是否為const解析調用。 在您的示例代碼中, test不是const ,因此調用了非const重載。

如果你這樣做:

testType test;
const testType &test2 = test;
test2->x();

你應該看到另一個重載被調用,因為test2const

test是一個非常量對象,因此編譯器會找到最佳匹配項:非常量版本。 您可以使用static_cast應用static_cast<const testType&>(test)->x();static_cast<const testType&>(test)->x();

編輯:順便說一句,當你懷疑 99.9% 的時間你認為你發現了一個編譯器錯誤時,你應該重新訪問你的代碼,因為可能有一些奇怪的怪癖,而且編譯器實際上是在遵循標准。

Data::x是否為常量函數並不重要。 被調用的運算符屬於container<Data>類而不是Data類,並且其實例不是常量,因此調用的是非常量運算符。 如果只有常量運算符可用或者類的實例本身是常量,那么常量運算符將被調用。

但是testType不是 const 對象。

因此它將調用其成員的非 const 版本。
如果方法具有完全相同的參數,則必須選擇調用哪個版本(因此它使用 this 參數(隱藏的參數))。 在這種情況下,這不是 const,因此您將獲得非常量方法。

testType const test2;
test2->x();  // This will call the const version

這不會影響對 x() 的調用,因為您可以在非 const 對象上調用 const 方法。

暫無
暫無

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

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