因此,我們正在研究範圍守衛或類似機制的使用,以確保傳入/傳出對象有效性和/或內部狀態不變,類似於C#代碼合同。使用範圍守衛作爲代碼合同
在正常處理過程中出現意外情況/異常而導致某些對象處於不一致狀態的特定情況下,我們可以/應該使用什麼機制來支持這一事實:範圍防護當我們跳出這個函數時會抱怨嗎?
下面是一些示例僞代碼來說明我的觀點:
struct IObjectValidator;
struct ObjectValidatorScopeGuard
{
ObjectValidatorScopeGuard(IObjectValidator * pObj)
: m_ptr(pObj)
{
Assert(!m_ptr || m_ptr->isValid());
}
~ObjectValidatorScopeGuard()
{
Assert(!m_ptr || m_ptr->isValid());
}
private:
IObjectValidtor * m_ptr;
};
int SomeComponent::CriticalMethod(const ThingA& in, ThingB& inout, ThingC * out)
{
ObjectValidatorScopeGuard sg1(static_cast<IObjectValidator *>(&in));
ObjectValidatorScopeGuard sg2(static_cast<IObjectValidator *>(&inout));
ObjectValidatorScopeGuard sg3(static_cast<IObjectValidator *>(out));
// create out
try
{
out = new ThingC();
out->mergeFrom(inout, out); // (1)
}
catch (const EverythingHasGoneHorriblyWrongException& ex)
{
// (2) out and inout not guaranteed valid here..
}
return 0;
}
所以,如果東西出了問題(1),導致「出」或「INOUT」是在一個糟糕的狀態在點(2)範圍守衛sg2/sg3將會拋出異常......而這些異常可能會掩蓋真正的原因。
是否有任何模式/約定來處理這種情況?我們是否錯過了明顯的東西
D'oh!愚蠢的我忘了沒有拋出dtors :-)我們的ASSERT宏實際上也拋出,很明顯,我們正在咆哮錯誤的樹。任何用於確定正確的「聰明的語句重新排序」的指針? – JBRWilkinson
+1,範圍警衛是爲了維護狀態,而不是斷言。另外,由於'Assert'實際上並沒有在這種情況下拋出任何東西,所以你可以使用常規的'assert'宏。 – Potatoswatter
@JBRWilkinson:我現在無法在互聯網上找到一個例子,所以我剛剛添加了一個簡單的例子。 –