[英]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();
你應該看到另一個重載被調用,因為test2
是const
。
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.