2017-05-08 104 views
-3

關於產品低垂從基類派生的類,以下的例子:C++中,如何將基礎對象向下轉換爲派生對象?

與(2)(3)(4),有助於解釋指針參考 futher之間的差異? (3),如何解釋g ++給出的錯誤信息;

class Base {}; 
class Derived : public Base {}; 

int main() 
{ 
    // example (1) 
    Derived d; 
    Base* b = &d; // its ok, implict 

    // example (2) 
    Derived d; 
    Base* b = &d; 
    Derived* d2 = (Derived*)b; // its ok! 

    // example (3) 
    Derived d; 
    Base& b_ref = d; // its ok, implict 
    Derived& d_ref1 = (Derived)b_ref; // error, error: no matching function for call to `Drievd::Drievd(Base&)' 

    // example (4) 
    Derived& d_ref2 = *((Derived*)(&b_ref)); // its ok 
} 
+1

「關於從派生類向超類下降的問題」 – juanchopanza

+0

@StoryTeller感謝提醒,它是我的錯! – Jcppython

+0

示例3應該是Derived&d_ref1 =(Derived&)b_ref;'以匹配較早的模式 –

回答

1
// example (2) 
Derived d; 
Base* b = &d; 
Derived* d2 = (Derived*)b; // its ok! 

B是一個指向Base,你可以明確地將它轉換爲一個指向Derived,只要它實際上是正確的類型。由於C風格演員不會將dynamic_cast作爲其attempted conversion的一部分,所以如果有失敗的可能性並且您的類實際上是多態的,則不應該進行C風格演員陣容。

// example (3) 
Derived d; 
Base& b_ref = d; // its ok, implict 
Derived& d_ref1 = (Base)b_ref; // error, error: no matching function for call to `Drievd::Drievd(Base&)' 

您還沒有轉換成一參考,(Base)b_ref通過複製它們由b_ref提到的相關部分一個新的臨時Base對象。錯誤是因爲您無法將Derived引用綁定到Base而沒有進行強制轉換,因此編譯器會嘗試創建一個臨時對象Derived,但Derived上沒有這樣的構造函數。即使有這樣的構造函數,它仍然不起作用,因爲您定義的左值引用是非const的,並且不能綁定到臨時對象。

// example (4) 
Derived& d_ref2 = *((Derived*)(&b_ref)); // its ok 

此工作方式相同的例子(2),不同之處還解除引用新轉換的指針值,從而獲得一個左值參照Derived對象,它高興地結合d_ref2

+0

不知道你在「從C風格的演員陣營」這個句子中想表達什麼觀點。在這種情況下,C風格轉換與'static_cast'相同,而'dynamic_cast'將無法編譯(非多態類型) –

+0

@ M.M - Huh?從OP派生類Derived:public Base {};' – StoryTeller

+0

是的,我知道這個...... –

0

在實施例3,您正嘗試從基類對象轉換爲派生類對象。編譯器抱怨,因爲你沒有在Derived中定義的構造函數,它會讓你做這樣的事情。編譯器不提供免費的這樣的構造函數。這通常不是一個有效的例子,但可能在一些獨特的情況下,雖然不是一個推薦的做法。您可以使用static_cast解決編譯器錯誤,但如果嘗試使用Derived中可用但不在Base中的某些內容,則可能會遇到意外的運行時錯誤。

相關問題