2014-03-28 52 views
4

我正在經由高斯消去解決方程以矩陣形式的系統的程序。然而,我遇到了一個有趣的問題:如果我的算術運算符通過引用傳遞,行的規範化會產生不正確的結果。通行證通過引用,源被修改運行中示

我在執行中,矩陣是由多種載體的,所以行操作只是矢量運算。以下是相關的功能:

載體:

T& operator[] (const int i); 
const T& operator[] (const int i) const; 
Vector<T>& operator/=(const T& rhs); 

template<class T> 
Vector<T>& Vector<T>::operator/=(const T& rhs) 
{ 
    if (rhs == 0) 
    { 
    throw DivideByZeroException(); 
    } 
    for (int i = 0; i < _size; ++i) 
    { 
    _data[i] /= rhs; 
    } 
    return *this; 
} 

矩陣:

Vector<T>& operator[] (const int i); 
const Vector<T>& operator[] (const int i) const; 

(以這種方式,單個[]用於訪問一排,和雙[ ] []是用於訪問的元素)

現在這裏是引起該問題的行:

mat[i] /= mat[i][i]; 

的這裏的問題是,這種操作在某些時候修改mat[i][i],然後使用修改的值,因爲operator/=通過參考使用通行證。

問題:它會更好改變經營者(以及所有類似的運營商),按值傳遞,或者只是改變所引起的問題行了?是否假定所有的操作員都會被引用,從而形成類似上面那樣的錯誤的行?

+1

我覺得你行'墊[I]/=墊[我] [我]'突破2序列points__之間的基本語言規則__no多種分配。那麼它不是一個規則,只是一個未定義的行爲。 –

回答

2

其實我覺得我要讓我的評論成爲一個完整的答案,這個問題不是來自您的/=運營商的實施,而是來自它的來電線路。就像我說的,這不應該給出可預測的(合法的)結果。因爲該語言在標準中說得非常清楚,並以i = i++ + ++i;爲例說明了這一事實。

所以我的建議是不要試圖讓這件事的工作作爲你的良好意願,爲您的客戶提供特殊的手勢,因爲客戶端誰做這打破的不僅僅是你的類規範更重要的合同。

+0

究竟是什麼兩處修改你覺得在這個程序中出現未測序單個對象? – Casey

+0

@Casey:這不是一個你提出的問題。它要求分解。我認爲在快速瀏覽之後,mat [i] [i]在矩陣行的divison期間被自身分割時被修改。所以它不正確,因爲它取決於除數是直接矩陣組件還是它的臨時副本。但是,如果我們把它看作'x/= x'是'x = x/x',那麼你就指出它對於順序規則來說是合法的。 –