[英]Wrong operator() overload called
我正在編寫一個矩陣類,並且兩次重載了函數調用運算符。 矩陣的核心是2D雙數組。 我正在使用從Windows控制台調用的MinGW GCC編譯器。
第一個重載旨在從數組中返回一個double(用於查看元素)。 第二次重載旨在返回對數組中某個位置的引用(用於更改該位置中的數據。
double operator()(int row, int col) const ; //allows view of element
double &operator()(int row, int col); //allows assignment of element
我正在編寫一個測試例程,並且發現從來沒有調用過“查看”重載。 由於某些原因,編譯器“默認”為調用使用以下printf()語句時返回引用的重載。
fprintf(outp, "%6.2f\t", testMatD(i,j));
我知道我通過編寫自己的矩陣類而不使用向量和使用CI / O函數進行測試來侮辱上帝。 我將在來世受到徹底的懲罰,無需在這里做。
最終,我想知道這里發生了什么以及如何解決。 我寧願使用看起來更干凈的運算符重載,而不是成員函數。
有任何想法嗎?
矩陣類:不相關的代碼被省略。
class Matrix
{
public:
double getElement(int row, int col)const; //returns the element at row,col
//operator overloads
double operator()(int row, int col) const ; //allows view of element
double &operator()(int row, int col); //allows assignment of element
private:
//data members
double **array; //pointer to data array
};
double Matrix::getElement(int row, int col)const{
//transform indices into true coordinates (from sorted coordinates
//only row needs to be transformed (user can only sort by row)
row = sortedArray[row];
result = array[usrZeroRow+row][usrZeroCol+col];
return result;
}
//operator overloads
double Matrix::operator()(int row, int col) const {
//this overload is used when viewing an element
return getElement(row,col);
}
double &Matrix::operator()(int row, int col){
//this overload is used when placing an element
return array[row+usrZeroRow][col+usrZeroCol];
}
測試程序:無關代碼被省略。
int main(void){
FILE *outp;
outp = fopen("test_output.txt", "w+");
Matrix testMatD(5,7); //construct 5x7 matrix
//some initializations omitted
fprintf(outp, "%6.2f\t", testMatD(i,j)); //calls the wrong overload
}
僅當對象為const時,才會調用const成員函數(“查看”函數):
const Matrix testMatD(5,7);
testMatD(1, 2); // will call the const member function
調用的重載僅由參數(包括this
參數)確定,而不取決於返回類型或您對返回類型的處理方式。
這意味着,如果您有一個非const
方法,該方法的簽名與const
方法相同(除了可能的返回類型),那么只有在const
對象或通過const
引用調用const
方法時,才會使用const
方法。或指針。 當你有一個非const
對象,則非const
方法將永遠是一個更好的匹配。
通常,唯一區分您是否實際寫入返回對象的方法是返回某種代理對象,該代理對象具有用於讀取的適當隱式轉換和用於寫入的重載賦值運算符。 不用說,這通常會增加相當大的復雜性。
嘿,謝謝大家的幫助,我對類似問題也有類似的回答。 我想我只需要再聽一次,措詞略有不同。
我最初的問題是,我需要兩個版本的運算符重載來實現,具體取決於調用該運算符的方式。
-當用戶只需要讀取一個值時,重載會將矩陣視為const並進行邊界檢查,以確保用戶未嘗試讀取不存在的數據。 -當用戶需要寫入數據時,過載將相應地調整矩陣的大小。
當然,這是沒有意義的,因為被調用的方法不知道正在調用什么或用戶正在嘗試做什么(除非傳入了一些數據)。
我的解決方案是使操作員重載對於讀取和寫入執行相同的操作。 因此,如果用戶嘗試讀取不存在的位置,則矩陣將自行調整大小並返回默認值。 最終,如果用戶犯了一個錯誤並讀取了不存在的數據,這可能會犧牲一些速度,但是如果用戶這樣做了,那么程序的速度便是他所擔心的最少的了。 因此,這需要用戶多加注意,並且我可能會添加一個數據成員,該成員是一個標志,用於指示矩陣是否已調整大小以輕松地允許用戶檢查事情是否按預期進行。
我將不發布代碼(除非要求),因為這是一個高級/功能性問題,並且代碼包含太多細節,可能會使討論蒙上陰影。
正如其他人提到的那樣,您需要一個const
對象才能調用const
重載。
您要在此處執行的操作是確保將引用轉換為...
的右值。
fprintf(outp, "%6.2f\t", double( testMatD(i,j) ) ); // double() for temporary
但是,該轉換是自動執行的(第5.2.2 / 7節),因此無需特別考慮。
另外,您最好聲明兩個重載以匹配。 使“查看器”也返回引用。
double const &operator()(int row, int col) const ; //allows view of element
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.