2012-06-26 149 views
2

我想完全理解轉換,即確保知道函數調用何時會導致隱式轉換,以及何時會導致編譯錯誤。 我已經瞭解到,轉換可以做,當且僅如果有轉換變量從下面的列表中最多兩個步驟,一個奇異的方式(按優先級排序):轉換和向上轉換

1. Exact match 
2. Promotion 
3. Conversion 
4. User defined conversion 

哪裏,路我理解它(你可能會糾正我),推廣是將原語轉換爲更大的原始類型,例如短到int,從float到double等等;轉換是不是促銷的基元之間的任何轉換,例如int到char等;用戶定義的轉換是使用轉換構造函數和轉換運算符的類的轉換。 現在,我也知道繼承的意思和Is-A關係,這意味着派生類是基類,因此將派生類發送到期望對基類的引用的函數應該起作用。結合以上兩個概念,我們應該得到的是下面的例子中我寫的,應該工作:

class C {}; 
class D: public C 
{ 
public: 
D(int x){} 
}; 
void f(C& c) {} 
f(3); 

由於d可以從int轉換到,和d是C.但這個代碼是不是被編譯。這是爲什麼?矛盾如何解決?你能否就這個問題提出一些看法?謝謝!

回答

4

代碼不會編譯,因爲轉換會創建一個臨時的,它不能綁定到非const引用。

如果你通過參數const參考(或按值,但我不建議你這樣做),它將工作。

您還需要基類中的轉換構造函數(如下所述)。

class C { 
public: 
   C(int x){} 
}; 
class D: public C 
{ 
public: 
   D(int x):C(x){} 
}; 

void f(const C& c) {} 
f(3); 

這是因爲隱式轉換隻適用於最大的一個次。在你的情況下,從int -> DD -> C一個直接轉換,所以int不能隱式轉換爲C

+0

@Als我沒看到基類。如果他在基類中有一個轉換ctor,它將會。 –

+0

關於常量,你是完全正確的。但是你確定「隱式轉換最多隻能應用一次」嗎?我被教導隱式轉換最多可以應用兩次。 – nodwj

+0

@Idan是的。它不能(邏輯上)。任何大於1的限制都會產生歧義。 –