[英]Using nested if statements to structure code
我試圖以一種可讀的方式來構造我的代碼。 我已經讀過一種方法,如下所示:
if(Init1() == TRUE)
{
if(Init2() == TRUE)
{
if(Init3() == TRUE)
{
...
Free3();
}
Free2();
}
Free1();
}
我喜歡這種處理方式,因為它將每個FreeX
在其匹配的InitX
循環中,但是如果嵌套超過三層,它將很快變得不可讀,並超過80列。 可以將許多功能分解為多個功能,以免發生這種情況,但是為了避免太多層次的嵌套而分解一個功能似乎很愚蠢。 特別是,請考慮對整個類進行初始化的函數,其中該初始化需要十個或更多函數調用。 那是十層或更多層的嵌套。
我敢肯定,我想得太多了,但是上面我缺少一些基本的東西嗎? 能否以可讀的方式進行深度嵌套? 還是以某種方式進行了重組,同時將每個FreeX
在自己的InitX
循環中?
順便說一句,我意識到上面的代碼可以壓縮為if(Init1() && Init2()...
,但是該代碼只是一個例子,在每個InitX
調用之間會有其他代碼可以防止這種壓縮。
由於包含了C ++標記,因此應該使用RAII-資源獲取正在初始化。 有很多很好的在線資源解釋了這個概念,這將使很多與資源管理有關的事情變得更加容易。
我敢肯定,我想得太多了,但是上面我缺少一些基本的東西嗎? [...]還是以某種方式進行了重組,同時將每個FreeX保留在自己的InitX循環中?
是。 這是一個代碼的教科書案例,將從RAII代碼中受益匪淺:
而不是構造:
if(init(3) == TRUE)
{
free3();
}
考慮一下:
raii_resource3 r3 = init3(); // throws exception if init3 fails
// free3 called internally
// by raii_resource3::~raii_resource3
您的完整代碼將變為:
raii_resource1 r1 = init1();
raii_resource2 r2 = init2();
raii_resource3 r3 = init3();
您將沒有嵌套的ifs,您的代碼將清晰明了(並專注於肯定的情況)。
您將只需要為資源1、2和3編寫RAII包裝器。
正如其他人指出的,顯而易見的答案是RAII。 但是,如果在沒有RAII的情況下出現了過度深層嵌套的問題,那么您應該真正問問自己,您是否沒有使函數過於復雜。 一個函數很少包含超過十行(包括此類檢查)。 如果查看實際案例,您會發現分解功能幾乎總是更有意義。 即使使用RAII,每個函數通常也應該只有一個RAII類實例。 (當然也有例外;可以說,類似std::lock_guard
類的東西不應該算在內。)
我建議使用的是switch語句。 當涉及到這樣的代碼時,我非常喜歡switch語句
希望這可以幫助。
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}
您可能聽說過gotos是邪惡的,但是如果您堅持使用c,那么使用gotos處理此類異常並沒有什么“骯臟”:
foo()
{
if (!Init1())
goto Error1;
if (!Init2())
goto Error2;
...
...
Error2:
Free2();
Error1:
Free1();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.