2016-11-07 35 views
25

VS2015中以下代碼的輸出是「構造函數」。構造函數是否應該被賦值?

由於缺少賦值運算符,不應該編譯失敗嗎?

struct A { }; 

struct B { 
    B(){} 
    B(const A& a) { 
     cout << "constructor" << endl; 
    } 

    //B& operator=(const A& a) { 
    // cout << "assignment operator" << endl; 
    // return *this; 
    //} 
}; 

int main() { 
    A a; 
    B b; 
    b = a; 

    return 0; 
} 
+1

這對你很有用:http://stackoverflow.com/questions/3734247/what-are-all-the-member-functions由編譯器創建的一個類似於do-hap- – SenselessCoder

+0

Bu那些不處理任何轉換,如從A到B,對嗎? – bitwise

+0

哦,我現在看到它了,我認爲它是其中之一,B是從A.繼承A.道歉。在這種情況下,我認爲有一些奇怪的事情發生。這可能是編譯器的事情。 – SenselessCoder

回答

29

是的,當有轉換正在進行時,就像在你的測試用例中一樣。

你有效地調用

b = B(a); 

因爲B的賦值操作符B& operator=(B const&)是隱式聲明,它重載解析過程中被發現。由於您的分配只是一次轉換而不是匹配(並且這恰好是允許發生的轉換次數),因此它會將a轉換爲B,然後將新的臨時B分配給b

13

讓我們考慮一個類似的例子。

double a; 
int b=5; 

a=b; 

可以分配給一個double的唯一事情是另一個double。但是,int可以轉換爲double

同樣在這裏,A可以轉換爲B,因爲這樣做的構造函數存在。那就是發生了什麼。

+2

那麼,你可以給'double'分配一個'int'。這個定義的行爲是'int'被隱式轉換爲'double',並且該轉換的結果替換了'double'的存儲值。也許最好是說「唯一可以存儲在double變量中的是'double'值,或者其他東西。 –

10

您的代碼已隱式從A轉換爲Bb = a編譯爲b = B(a);。如果你想這是作爲錯誤檢測,你可以使用the explicit specifier

struct B { 
    B(){} 
    explicit B(const A& a) { 
     std::cout << "constructor" << std::endl; 
    } 
}; 

那麼你應該得到的錯誤,如these generated by ideone.com

prog.cpp: In function 'int main()': 
prog.cpp:20:7: error: no match for 'operator=' (operand types are 'B' and 'A') 
    b = a; 
    ^
prog.cpp:5:8: note: candidate: B& B::operator=(const B&) 
struct B { 
     ^
prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'const B&' 
prog.cpp:5:8: note: candidate: B& B::operator=(B&&) 
prog.cpp:5:8: note: no known conversion for argument 1 from 'A' to 'B&&' 

之後,構造函數將永遠不會被隱式調用,如果你想打電話給你,你必須明確地寫下:b = B(a);

+2

很好的提及'explicit'關鍵字 – Michael

相關問題