2015-04-27 123 views
3

考慮這種情況下:隱式轉換C++

ClassA obA; 
ClassB obB; 

obA = obB; 

是它的權利,如果ClassA具有己ClassB類型的參數的構造函數,它將在這種情況下,叫什麼?

如果ClassB中存在重載的鑄造操作符 - 將ClassB對象轉換爲ClassA對象,則會調用操作符方法。如果有相應的構造函數和重載的鑄造操作符會調用哪一個?我在哪裏可以讀到它?

+0

看看這個問題,它可能會幫助你: http://stackoverflow.com/questions/1092714/conversion-precedence-in-c –

+0

這不是鑄造,這是轉換。 – molbdnilo

+0

一旦我們通過調用構造函數來獲得OP對operator =的混淆,這似乎回答了這個問題:http://stackoverflow.com/questions/1384007/conversion-constructor-vs-conversion-operator-precedence –

回答

3

是它的權利,如果ClassA具有己ClassB類型的參數的構造函數,它將在這種情況下,叫什麼?

是,構造函數被認爲是隱式類型轉換:類對象的

類型轉換可以通過構造和通過轉換函數來指定。這些 轉換稱爲用戶定義的轉換,用於隱式類型轉換(第4章), 初始化(8.5)以及顯式類型轉換(5.4,5.2.9)。

與簽名ClassA::ClassA(ClassB)構造函數被稱爲轉換構造函數。在諸如賦值之類的函數調用期間,構造函數和用戶定義的轉換運算符被編譯爲過載集合,並且爲轉換選擇最好的一個。

如果選擇一個構造:如果源類型是類型數值,它創建與所述目標類型(ClassB)的類型初始化的源類型(ClassA)的類型的一個prvalue,那就是用於初始化參數。如果源類型是引用,則使用reference-initialization rules


賦值運算符在ClassA隱含生成的(假設他們沒有被重寫)。它們是:

ClassA& operator=(ClassA const&); 
ClassA& operator=(ClassA  &&); 

了隱式轉換序列可以選擇一個構造函數或轉換函數從ClassB -> ClassA const&ClassB -> ClassA&&轉換。

但是,在這種情況下,根據您的情況,轉換將無法成功,因爲它會變得模糊不清。試想一下:

struct B { operator struct A(); }; 

struct A { 
    A() = default; 
    A(B) {} 
}; 

B::operator A() { return A(); } 

int main() 
{ 
    A a; B b; 
    a = b; // Error! Ambiguous conversion 
} 

兩個A::A(B)B::operator A()都是可行的轉換功能,以用於轉換。因此,轉換是不明確的,我們被給出編譯錯誤。

用戶定義的轉換隻應用於明確的地方(10.2,12.3.2)。

如果我們改變A類的轉換構造函數的簽名A::A(B const&),然後在B轉換運營商將使用,因爲A的構造函數需要一個資格轉換(加const)。

cppreference有一個線程,您可以在這裏瞭解更多。

3

此代碼:

ClassA obA; 
ClassB obB; 

obA = obB; 

是不是你認爲它是(*)。此代碼:

ClassB obB; 
ClassA obA = obB; 

將工作(如提供),如果:

1.ClassA具有構造函數,它接受作爲ClassB參數:

class ClassA 
{ 
public: 
    ClassA(const ClassB& b) 
    { 
     //construct *this from b 
    } 
}; 

2.ClassB已經定義轉換爲類型的運算符:

class ClassB 
{ 
public: 
    operator ClassA() const 
    { 
     //construct ClassA from *this 
    } 
}; 

如果在ClassA中有一個重載的鑄造操作符,它具有類型ClassB [...]的參數。

你的意思構造,不鑄造操作,對不對?您嘗試將ClassA轉換爲ClassB,因此在這種情況下,來自ClassA的轉換運算符無關緊要。


(*)你之後obA的建設分配obBobA,所以在你的情況下,只有第二點是適用的。你也可以把它加入賦值運算符的工作:

class ClassA 
{ 
public: 
    ClassA& operator=(const ClassB& b) 
    { 
     //assign b to *this 
    } 
}; 

這將在你的情況下被調用。

+0

是的,它是一個錯誤,我編輯了這個問題。謝謝。 –

+0

關於#1的好電話。值得注意的是,如果有人同時嘗試#1和#2,那麼他們會遇到循環參考問題。 – AndyG