2012-12-01 103 views
0

假設我有以下三類:繼承和隱式類型轉換

class Animal {}; 

class Human : public Animal {}; 

class Dog : public Animal 
{ 
public: 
    void setOwner(Animal* owner) { this->owner = owner; } 
private: 
    Animal* owner; 
}; 

爲什麼下面允許的,究竟是怎麼回事?

Dog d; 
Human h; 

d.setOwner(&h); // ? 

起初,我試圖投它這樣d.setOwner(&(Animal)h),但是編譯器給了我一個警告,我打了一個運行時錯誤。

編輯:編譯器給我的警告是「以暫時的地址」。這是爲什麼?

回答

1

這裏 d.setOwner((動物)& 1H)

你嘗試下的指針類型對象類型。你不能這樣做。

鑄造動物類的正確方法是

d.setOwner((Animal*)&h) 

但你

d.setOwner(&h); 

使用,因爲在C指針,如果需要++被自動轉換爲一個基類。顯式轉換爲Animal *不是必需的。

1

沒有類型轉換,但Human是安Animal。因此,任何作用於Animal*的接口都將接受Human*。這同樣適用於Animal&Human&。當然,他們只看到對象界面的Animal部分。

1

當別人pionted了沒有必要投下衍生*立足*

,但沒有人answerd問題的警告。 是的,有一個臨時動物創建。而不是鑄造指針,將對象本身從人類所有者轉移到動物。這導致了人類所有者創造了一個臨時動物。這個臨時地址被傳遞給設置的功能。當二傳手迴歸臨時人類消沉者時,可憐的狗主人指針是無效的。

所以總是讀警告。如果你不明白他們認爲他們是錯誤的。

另一個問題 - 避免構造函數元素和成員具有相同的名稱或有一天,你會學習這個規則的困難。