2012-12-07 69 views
2

我正在寫一個程序,我創建了一個std :: POD結構的向量。該結構的一個成員是唯一標識符。應該在這種情況下運營商==或!=投擲?

爲了能夠使用std :: binary_search,我必須爲結構實現運算符<。遵循指南here,我正在爲==,!=,<,>,> =和< =寫入整套重載。

這提出了一個問題,我不知道如何處理。該矢量將按照我分配每個結構的唯一ID進行排序。如果兩個結構具有相同的標識符,則它們是相同的。但是,如果兩個結構體在其他成員中具有相同的標識符但數據不同,那麼情況就會出現。

這不應該發生。讓比較運算符檢查剩餘的字段,然後拋出異常(如果它們不同但ID相同)是否合適?什麼樣的例外將是最合適的?

+2

我認爲一個'std :: set'與基於id的比較更適合這個任務。 – chris

+3

如果你希望這個條件在運行時是可以恢復的,那麼'throw'就是合適的。如果不是,'assert'可能是更好的選擇。 – phonetagger

+0

@chris我去了std :: vector,因爲我需要內存連續。我不知道該集(或任何其他有序容器)提供了這種保證。 – Kian

回答

7

這僅僅是對SCombinator's answer.

,你說的其實是一個擴大「這應該不會發生。」意味着你想使用一個斷言,而不是一個例外(或兩者的組合)。一個例外會隱藏錯誤 - 好吧,不會隱藏,但你可以抓住它並繼續。它更適合於你沒有真正計劃的特殊情況 - 例如,你試圖打開一個不存在的文件。這不是邏輯的一部分,該文件不存在,它是你的小弟不小心刪除了你的文件,或者是一種認爲它是病毒的激進反病毒,或者其他 - 這只是一種特殊情況。

如果具有相同ID但不同的成員是不應該發生的事情,那基本上就是斷言。這是邏輯的一部分 - 如果你願意的話,這是要求的一部分。拋出一個異常只是指出了這一點,但並沒有真正的方法可以從中恢復。當你意識到錯誤的時候,已經晚了2點。你有兩個具有相同ID的對象,但不同,你不知道哪一個是正確的,你不知道爲什麼不正確的對象存在,等等。你可能甚至不想從中恢復。應用程序已經處於錯誤狀態 - 兩個相互矛盾的對象已經存在。你的應用程序處於不可恢復狀態 - 如果你繼續這樣做,你可能會得到錯誤的結果或更糟的結果。

如果它不是一個關鍵的斷言,你也可以隨後拋出異常,並提供一個乾淨的方式來關閉應用程序,但這只是一種美化。

一般來說,我遵循一個簡單的規則 - 如果是在特殊情況下可能發生的事情,我會使用例外。如果它永遠不會發生,如果它確實存在,意味着代碼中的邏輯嚴重錯誤,我使用斷言(也可能是強制崩潰)。

+0

謝謝。然而,只是爲了澄清一點,如果ID是相同的,並且成員不同,則不會發生錯誤。 – Kian

+0

@Kian啊,好的。現在好多了? (雖然沒有改變推理):) –

+0

是的,謝謝你的解釋。它確實使它更清楚何時使用它們。 – Kian

2

如果這樣的事情是一個邏輯錯誤,你應該使用一個assert

+0

斷言在這裏使用是正確的,但是你可能想要擴展爲什麼,以及爲什麼它比這種情況下的例外更好。 –

0

你可以使用一個map這是一個二叉搜索樹實現,雖然你會複製一個id。再次,你甚至不需要將id存儲在結構中,因爲它們應該是唯一的。

// Example POD struct. 
struct MyStruct 
{ 
    int id; // Redundant. 
    char a;  
} 

std::map<int, MyStruct> myMap; 
MyStruct m; m.id = 1; 
myMap[m.id] = m; 
// Or simply.. 
myMap[1] = m; 
2

好了,你要問自己幾個問題:

1)這是可能發生的測試(如信號的錯誤),但在正常執行過程中不會發生?如果答案是肯定的,請使用assert

2)這是否會在正常運行時發生,如果是這樣,程序是否可以恢復並繼續執行?如果答案是肯定的,那就拋出一個錯誤,抓住並處理它。

3)這是否會在正常運行時發生並且是不可恢復的?如果是,請撥打abort或類似的東西(exit, terminate)或拋出一個你不打算處理的異常。

+0

如果只有1)那麼簡單。如何判斷是否只在測試期間發生了某些錯誤,但從未在正常執行期間發生錯誤 –

+0

或者希望最好,或者完全停止使用assert,我想。 (我的意思是使用完整的測試而不是斷言。) 它並不總是很簡單。但有時可能。 –

1

創建數據時應該拒絕不良數據。比較運營商不去清除錯誤;那麼應該在之前完成該程序執行任何嚴重的數據操作。所以這個問題的答案是否定的,operator==operator!=不應該對不良數據拋出異常;他們應該假設傳遞給他們的數據是有效的。