2016-10-30 48 views
1

我正在寫一個矩陣的計算類(用於練習的緣故),當我寫的方法來乘兩個矩陣的計算對象,我不得不檢查,如果某些條件得到滿足的矩陣乘法:如果某些條件沒有得到滿足,從方法返回什麼?

Matrix Matrix::mul(const Matrix &mat) 
{ 
    if(col != mat.row) 
     //we cannot multiply in this case 
    else 
    { 
     //create temp object result 
     //perform multiplication 
     return result; 
    } 
} 

現在我很好奇在做什麼,如果條件沒有得到滿足,因爲早在main.cpp中我會寫這樣的事:

Matrix a = b.mul(c); 

現在,如果b和C不能乘什麼,我應該怎麼回報? 是引發異常的最好方法,只是強制使用該類的人發送兼容的矩陣,還有另一種更好的方法嗎?

+0

返回'std :: optional',或拋出。 – Incomputable

+0

如果您的矩陣具有固定的大小(和編譯時間常量),則可以將這些大小移動到模板參數中。然後(假設你的簽名是正確的),編譯器不會讓你乘以錯誤大小的矩陣:) – StoryTeller

+0

它們是動態創建的,但是謝謝 – adadaae12313412

回答

2

不要返回任何東西,拋出exception代替:

if (failure) 
    throw std::runtime_error("Exception!!"); 

你可以拋出任何適合你的情況越different exceptions的。

順便說一句,你可以看看我的項目Matrixon GitHub關於如何創建這樣一個類來操作矩陣的例子。

2

爲了應對先決條件,你可以

  • 拋出一個異常。
  • 返回C++ 17 std::optionalboost::optional
  • 致電std::terminate

破壞前置條件通常意味着調用代碼中的邏輯是錯誤的。因此,一種常見的做法是僅僅對assert進行前提條件和廣泛的測試。理想情況下,這將確保前提條件永不中斷。

爲了幫助調用代碼,最好爲它提供一種方法來檢查的調用是否會失敗。

1

有什麼可能的方法?

  1. 返回,顯示有一個問題(例如空矩陣)的一些中性值
  2. 處理錯誤,而只是在調試時:例如使用assert()來驗證和記錄事前和事後條件以及不變量。
  3. 拋出一個異常來通知存在問題:讓調用者(或調用者的調用者)決定要做什麼。如果該異常未被捕獲,代碼將中止。好的是你可以提供額外的錯誤信息。

您應該選擇哪一個?

如果錯誤情況頻繁(幾乎正常)並且經常調用該函數,則應該使用解決方案(1)。我不建議你在這裏使用它。

如果預計不會出現錯誤情況,並且您有信心防止錯誤情況(例如,用戶界面可以防止發生此類錯誤),則可以使用解決方案(2)。解決方案(3)適用於錯誤情況沒有真正預期且無法防止的情況。據我所知,這應該是你的矩陣乘法的一個很好的候選解決方案。

示例解決方案3

而不是使用一個通用exception或創建自己的特定的一個,你可以使用domain_error(域在數學意義上,即參數是一個有效的價值,但功能不使用該值)或invalid_argument定義:

// in your multiplication 
... 
if(col != mat.row) 
    throw std::invalid_argument ("Matrix multiplication operand of incompatible size"); 
... 

// In the calling program: 
... 
try { 
    a = b.mul(c); 
} 
catch (std::invalid_argument &e) { 
    cout << "Invalid argument provided: " << e.what()<<endl; 
} 
0

,我應該回報?

這取決於您的要求。

是拋出一個異常

這可能是最好的辦法。這取決於你的要求。


您有幾種選擇:

  1. 終止進程。開發人員可以分析核心轉儲以確定發生了什麼。這樣做的好處是一個錯誤很難錯過。

  2. 甚至不測試函數內的先決條件。簡單說明前提條件。如果調用者違反前提條件,則行爲未定義。這是最有效的解決方案,但依賴於該功能的用戶正確使用它。

  3. assert測試條件。如果測試失敗,則該過程終止。通過NDEBUG宏,斷言被禁用,因此您可以禁用該檢查以獲得最佳性能。這允許選擇1或2,具體取決於調試vs發佈構建,因此比兩者更靈活。

  4. 拋出異常。這允許調用者忽略如果無法處理失敗的可能性,並讓調用堆棧中的代碼更高處理它,或者如果無法處理該進程,則讓該進程終止。

  5. 返回std::optional。這允許調用者檢查是否有返回值並決定他們希望用來處理丟失的1 ... 4選項中的哪一個。如果調用者忽略不存在返回值的可能性,則默認爲2.(未定義的行爲)。

相關問題