2008-09-25 68 views
15

在C初始化變量++,你可以在if語句中初始化變量,像這樣:的Pro/CON:在條件語句

if (CThing* pThing = GetThing()) 
{ 
} 

一個爲什麼會認爲這是好還是壞的風格?有什麼好處和壞處?

就我個人而言,我喜歡這種風格,因爲它限制了pThing變量的範圍,因此它在NULL時不會被意外使用。但是,我不喜歡,你可以這樣做:

if (CThing* pThing = GetThing() && pThing->IsReallySomeThing()) 
{ 
} 

如果有一種方法,使上述工作,請發表。但如果這是不可能的,我仍然想知道爲什麼。

Question borrowed from here, similar topic but PHP.

回答

18

重要的是,C++中的聲明不是表達式。

bool a = (CThing* pThing = GetThing()); // not legit!! 

不能在一個如果兩者都做一個聲明和布爾邏輯語句,C++語言SPEC特別允許任一表達式或聲明。

if(A *a = new A) 
{ 
    // this is legit and a is scoped here 
} 

怎樣才能知道在表達式中一個詞與另一個詞之間是否定義了a?

if((A *a = new A) && a->test()) 
{ 
    // was a really declared before a->test? 
} 

咬住子彈並使用內部if。範圍規則是有用的,你的邏輯是明確的:

if (CThing* pThing = GetThing()) 
{ 
    if(pThing->IsReallySomeThing()) 
    { 
    } 
} 
2

應該 不起作用在C++ 因爲 即使它支持short circuiting evaluation 也許 不要嘗試以下方法:

if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing())) 
{ 
} 

犯錯..在條件看,因爲從一個未接「=」共同的bug Wesley Tarle's answer

+0

我會嘗試...我記得我試過各種支架放置,但沒有任何工作,雖然編譯器錯誤改變了很多取決於括號。 – steffenj 2008-09-25 22:30:19

+0

「短路評估」......我只知道這只是「早出」到目前爲止。這對我來說是新的。 – steffenj 2008-09-25 22:31:20

2

一個原因我通常不這樣做是測試。我使用lint,並設置錯誤/警告來捕捉這些錯誤/警告。然後它會大聲說出條件中的所有作業。

4

關於優點:

它總是建議當你第一次需要他們,之前不是一條線來定義變量。這是爲了提高代碼的可讀性,因爲我們可以在不滾動的情況下知道CThing是什麼,並可以在其中定義它的位置。

還將範圍縮小到循環/ if塊,導致變量在執行代碼塊後未被引用,這使得它成爲垃圾收集(如果語言支持此功能)的候選者。

2

只是一個FYI一些較舊的微軟C++編譯器(我認爲Visual Studio 6和.NET 2003)在某些情況下並不完全遵循作用域規則。

for(int i = 0; i > 20; i++) { 
    // some code 
} 

cout << i << endl; 

我應該超出範圍,但這是/是有效的代碼。我相信這是作爲一個功能發揮作用,但在我看來,這只是不合規。不遵守標準是不好的。就像一個關於IE和Firefox的網頁開發者一樣。

VS有人可以檢查,看看是否仍然有效?

+1

這是一個編譯器選項,「在for語句中強制範圍」或其他內容。 – 2008-09-25 22:40:28

+2

是的,它是/ Zc:forScope-「強制循環範圍內的一致性」。至少在VS 2008中。 – 2008-09-25 22:49:18

0

您也可以將該賦值放在額外的一組()中以防止出現警告消息。

0

我明白那是一種危險。下面的代碼更安全,封閉的大括號仍然會以您想要的方式限制pThing的範圍。

我假設GetThing()有時返回NULL,這就是爲什麼我把這個有趣的子句放在if()語句中。它防止在NULL指針上調用IsReallySomething()。

{ 
    CThing *pThing = GetThing(); 
    if(pThing ? pThing->IsReallySomeThing() : false) 
    { 
    // Do whatever 
    } 
} 
0

還注意到,如果你正在寫C++代碼,你想使編譯器警告有關「=」在條件語句(不是的一部分一個聲明)一個錯誤。

0

這是可以接受的和良好的編碼習慣。但是,不是來自低級編碼背景的人可能會不同意。

3
if (CThing* pThing = GetThing()) 

這是不良作風,因爲if裏面你是不是提供了一個布爾表達式。您正在提供CThing*

CThing* pThing = GetThing(); 
if (pThing != NULL) 

這是很好的風格。