2009-12-03 44 views
4

請考慮以下代碼。
這裏,即使構造函數是A(B & b),A a(B())也會編譯; 但是print(B())不起作用。但印刷品也被宣佈爲印刷品(B & b); 爲什麼這種不一致?將臨時變量傳遞給構造函數中的參考arg。但不是一般的功能。爲什麼?

#include <iostream> 
using namespace std; 

class B{ 
    public: 
      char b; 
}; 

class A { 
    public: 
      B b; 
      A(B& b); 
      A() { } 
}; 

A::A(B& b) { 
    this->b = b; 
} 

void print(B& b) { } 

int main(){ 
    print(B()); 
    A a(B()); 
} 

回答

6

它編譯,因爲它沒有創建一個A的實例。它聲明一個函數,它的名字爲a,它返回一個A並接收一個類型爲pointer-to-function-returning-B的未命名參數。因爲它只是一個聲明,所以它編譯。如果您在代碼中的其他地方提及a,則會看到其他問題。爲什麼這是一個函數聲明而不是對象定義,查找的術語是最令人頭疼的解析

+0

這太血腥糟糕! C++甚至允許你聲明一個函數INSIDE另一個函數嗎?爲什麼C++允許這樣做?爲什麼會有人需要這樣的設施? – user855 2009-12-03 04:32:05

+1

是的,C++確實允許。很明顯,因爲你剛剛做到了。它是一個函數內的聲明,因爲它是其他地方的聲明。將該行放在類聲明中,它是一個成員函數聲明。把它放在其他地方,這是一個函數聲明。無論你放在哪裏,都是一個函數聲明。 – 2009-12-03 04:43:36

+0

我認爲完全可以修改編譯器來添加條件,如果這樣的事情發生在函數的定義內部,它不是函數聲明,而是對象聲明。我很驚訝他們爲什麼決定不修復它。 – user855 2009-12-03 04:57:53

1

你不應該通過非經常提及一個臨時的,所以print聲明不應該編譯。如果您修改printconst中的引用,它將起作用。

3

此:

A a(B()); 

不是做你的想法。它實際上被解析爲函數聲明。這在C++中通常被稱爲「most vexing parse」(如果您搜索該短語,這裏有許多關於它的帖子)。

1

當您嘗試調用構造函數你actually declaring a function

A a(B()); 

這聲明a爲返回A,並採取作爲參數的函數指針返回B並採取無參數的函數。

實際上試圖調用一個錯誤的構造的結果,符合市場預期:

A a = A(B()); 

tst.cpp:32: error: no matching function for call to ‘A::A(B)’

相關問題