2013-11-20 91 views
0

我有這樣一段代碼:錯誤無效的轉換

class C 
{ 
    virtual vec3 f1(const A* a, B* b){...} 
    virtual vec3 f2(A const* a, B const* b) 
    { 
     vec3 color = f1(a, b); 
     ... 
    } 
} 

我想打電話給f1f2,但我不知道怎麼打發b在正確的方法。 現在在編譯時,我得到:

error: invalid conversion from 'const B*' to 'B* [-fpermissive]' 

我已經試過vec3 color = f1(a, const_cast<B *>(b));

這將編譯,但後來我得到執行分段錯誤。

請注意,我不能更改任何功能簽名。 例如,我也不能改變AB的定義來實現getCopy()函數。

UPDATE:

我發現返回B的修改後的副本,所以我的問題就解決了一個功能。 謝謝大家說服我停止嘗試將其直接投射到f1。

回答

3

如果您無法更改功能簽名,則無法解決您的問題。邏輯上,f2正在與來電者簽訂合同:「我將帶一個B *並使用它,但我保證我不會修改它指向的B」。如果您將該指針傳遞給的其他內容請修改B您已違反合同。如果f2旨在修改BB*它不應該是const(也許它應該是B&,作爲旁註)。

至於崩潰:修改最初聲明爲const的對象是未定義的行爲。實際上,這意味着編譯器可以自由地執行諸如將其存儲在只讀存儲器和其他棘手的事情中。如果您嘗試寫信給它,所有投注都關閉。它可能會崩潰。它可以工作。任何事情都可能發生。

+0

會解決方案是複製B,並傳遞該指針?顯然,當函數返回時,您不希望B發生更改。我同意這是一個難題... – Floris

+1

這將是奇怪的,因爲如果第二個函數修改指針,我會認爲這是因爲調用者*想要*這個新值。或者,如果沒有,那爲什麼會被修改? – CmdrMoozy

+1

@CmdrMoozy - 有效的點。但這基本上是簽名告訴你的。我認爲這是一個「學術演習」。 – Floris

1

唯一合乎邏輯的解決辦法是

virtual vec3 f2(A const* a, B const* b) 
{ 
    B mutableB(*b); 
    vec3 color = f1(a, &mutableB); 
    ... 
} 

運行時是免費的崩潰是因爲修改以前const聲明的變量後const_cast是不確定的行爲。我猜b原本是const,而f1試圖修改它。

從編譯器的POV考慮它:你需要兩個函數 - f1f2。您可以將常量參數傳遞給f2,從而保證您不會修改它們。但後來你嘗試將它們傳遞給f1,其中可以修改它們。

0

如果f1修改指針的目標,那麼f2;所以f2不能指向const對象。您必須從f2中刪除const,而不是嘗試用常量對象調用它。您不允許修改const對象,並且如果您嘗試執行,程序可能會崩潰(或者存在未定義的行爲)。如果f1不修改它,則將該指針更改爲const。這聽起來像是這樣。