2017-06-05 35 views
-1

東西讓我發瘋。爲什麼這會給我一個Java中的ClassCastException,而它在C++中運行良好?

假設我們有這些簡單的類

public class Animal { 
public void makeSound() { 
    System.out.println("From Animal"); 
    } 
} 

public class Dog extends Animal { 
public void makeSound() { 
    System.out.println("From Dog"); 
} 

public void flip() { 
    System.out.println("Flipped"); 
} 

public static void main(String[] args) { 
    Animal a= new Animal(); 
    ((Dog)a).makeSound(); // Gives me an error at runtime.  

} 

C++代碼:

class Animal { 
    public: 
      virtual void makeSound(){ cout<<" From Animal";} 
}; 

class Dog : public Animal { 
    public : void makeSound(){ cout<<" From Dog ";} 
      void flip() { cout<<"Flipped";} 
}; 

main() { 
Animal *a = new Animal(); 
((Dog*)a)->makeSound(); // returns From animal 

    } 

它爲什麼會生成Java運行時錯誤,而這將在沒有C++的一個問題工作?

謝謝

+0

它確實 「沒有問題的工作。」由於C傳統,這是未定義的行爲。 –

+2

狗是動物,但動物不一定是狗 –

+0

可能重複[顯式從超類轉換爲子類](https://stackoverflow.com/questions/4862960/explicit-casting-from-super-class-to -subclass) –

回答

4

你的例子不能正常工作;它的行爲是未定義的。

C++有幾種不同類型的投射操作。你在這裏使用的是C-style cast(技術上它最終做的是static_cast)。 C風格轉換不會執行任何運行時類型檢查。這取決於程序員確保所涉及的類型有意義。如果要運行時類型檢查,請使用dynamic_cast。在指針中使用dynamic_cast時,如果對象實際上不是要轉換爲的類型的實例,則該強制轉換將失敗並返回nullptr。當使用參考時,它會拋出std::bad_cast

class Animal { 
public: 
    virtual void makeSound() { std::cout << "From Animal\n"; } 
}; 

class Dog : public Animal { 
public: 
    void makeSound() { std::cout << "From Dog\n"; } 
}; 

int main() { 
    Animal *a = new Animal(); 
    Dog* d = dynamic_cast<Dog*>(a); 
    if (d == nullptr) { 
     std::cout << "cast failed\n"; 
    } else { 
     d->makeSound(); 
    } 
} 

Live example

0

向下轉型,纔可能(在Java中),如果在你的代碼中的一些點,你引用的子類如

Animal a = new Dog(); 
((Dog)a).makeSound(); 
+0

downvote的任何解釋將不勝感激。謝謝。 – anonymouse

+0

通常這是有效的,因爲我們現在說a是一隻狗,但只有動物的方法。 在這裏做一個低調,我們也可以訪問狗的方法。 所以makeSound()在這兩種情況下,直接調用之前和之後,向下轉換將始終返回From Dog。 P.S:我不會投票,因爲我沒有很多聲望。但我很感謝你的回答! – ZikoUdeM

相關問題