2013-07-25 13 views
0

如何首先執行tryout.main()cout,然後打印main()函數cout並最終打印tryout.main()的返回值。這有點令人困惑。任何人都可以解釋它嗎?C++ cout如何在這個程序中被執行?

#include<iostream> 
using namespace std; 
class TryOut 
{ 
public: 
int main() 
{ 
    std::cout<<"In TryOut Main Function "<<std::endl; 
    return 0; 
} 
}; 

int main(int argc, char **argv) 
{ 
TryOut tryout; 
std::cout<<"In Main function: "<<tryout.main()<<std::endl; 
return 0; 
} 

輸出:

In TryOut Main Function 
In Main function: 0 
+1

你到底在問什麼? – Borgleader

+0

@Borgleader他們可能期望有不同的順序。 – juanchopanza

+0

本質上,與[參數計算時,串聯調用時:obj.F1().F2().F3(sin(x))?](http://stackoverflow.com/問題/ 4713892 /時 - 被參數計算-時-具有-級聯-呼叫OBJ-F1-F2-F3/4714440#4714440)。 –

回答

4

這是經編輯的答覆。我被Igor Tandetnik證明是錯誤的,因爲我的回答是(錯誤地)被接受並且得票最高,我決定重寫它以使其正確。

在我們的情況

foo() = ostream& ostream::operator<<(const char*)

執行的在序列中的順序:

obj.foo("str").foo(fun())

可以是:

obj.foo("str"); 
fun(); 
obj.foo(fun_res); 

fun(); 
obj.foo("str"); 
obj.foo(fun_res); 

在你的情況下,後者發生了,但前者也是有效的執行順序。

順序擔保如下:

  • fun()會因爲foo的結果是必需的通話obj.foo(fun_res)發生之前,
  • obj.foo("str")obj.foo(fun_res)之前發生。

因此上述兩種情況是可能的。

+0

'主功能:TryOut主功能0'也可以合法生產。這是一個可能的執行順序。 –

+0

@IgorTandetnik不可以,因爲同樣的原因,爲什麼這個問題不是重複的(儘管這是我第一次提出這個問題)。 Dariusz是正確的,雖然它們之間的參數評估順序沒有指定,但在執行實際函數調用之前,必須評估所有參數。 – jogojapan

+0

難道是因爲級聯從右到左進行評估? –

2

一般而言,表達式中子表達式的評估順序是未指定的。在執行std::cout<<"In Main function: "之前或之後,可能會合法調用tryout.main()。在你的情況下,它恰好在之前被調用。

0

「< <」 在C++實際上是語法糖,當你做

cout << "Hello" 

你實際調用任何

ostream& operator<<(ostream&, const char*) 

ostream的&的ostream ::操作< <(const char *)

爲方便起見,我將假設後者。當你寫

std::cout<<"In Main function: "<<tryout.main()<<std::endl; 

這將彙編到

cout.operator<<("In Main function: ").operator<<(tryout.main()).operator<<(std::endl); 

所以你寫的

代碼
<<tryout.main()<< 

說:「叫tryout.main(),獲取返回值,傳遞給「ostream :: operator < <(int)」,使用前面的< <返回的ostream。

所以 - 現在tryout.main()被調用和執行,這確實是自己的輸出,相當獨立,然後返回0

現在你的主要功能是能夠完成它的調用鏈的返回值0作爲參數。

是否有一個原因,你無法通過調試器來完成這一步?

+0

是的。從入門我知道cout會從右到左執行。但這裏完全不同。所以它仍然是從右到左執行的? – kayle

+0

「cout」不執行,它是一個對象。你的意思是「<<」,並回答你的問題,http://ideone.com/mLmT10,或者通過一個調試器直接進入 - 在Visual Studio中使用F11按步進入每個函數調用,或進入gdb使用「s」而不是「n」。 – kfsone

+0

明白了。謝謝 – kayle