为啥这会给我一个 Java 中的 ClassCastException,而它在 C++ 中运行良好?
Posted
技术标签:
【中文标题】为啥这会给我一个 Java 中的 ClassCastException,而它在 C++ 中运行良好?【英文标题】:Why would this give me a ClassCastException in Java, while it works well in C++?为什么这会给我一个 Java 中的 ClassCastException,而它在 C++ 中运行良好? 【发布时间】:2017-06-05 04:01:47 【问题描述】:有些事情让我发疯了。
假设我们有这些简单的类
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++ 中却没有问题?
谢谢
【问题讨论】:
它确实“工作没有问题”。由于 C 遗留问题,这是未定义的行为。 狗是动物,但动物不一定是狗 可能与同一示例重复 explicit casting from super class to subclass 也许有些人会使用相同的示例,因为它在 Java 或 C++ 教程网站上随处可见,但只是在 Java 和 C++ 中使用相同的示例,我发现在 Java 中出现错误,而C++ 中没有错误,它执行没有问题 @ZikoUdeM 这不是 C++ 的错。 C 风格的转换只是不做任何运行时类型检查。如果需要,请使用dynamic_cast
。
【参考方案1】:
您的示例无法正常工作;它的行为是不确定的。
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
【讨论】:
【参考方案2】:只有在代码中的某个位置引用子类时(例如,在 Java 中)才可能进行向下转换
Animal a = new Dog();
((Dog)a).makeSound();
【讨论】:
对否决票的任何解释将不胜感激。谢谢。 通常这是有效的,因为我们现在 a 是一只狗,但只有 Animal 的方法。在这里进行向下转换时,我们也可以访问 Dog 的方法。因此,在这两种情况下,如果在向下转换之前和之后直接调用 makeSound() 将始终返回 From Dog。 P.S:我不会投反对票,因为我没有很多声誉。但我很感谢你的回答!以上是关于为啥这会给我一个 Java 中的 ClassCastException,而它在 C++ 中运行良好?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 TypeScript 中的 'instanceof' 会给我错误“'Foo' 仅指一种类型,但在这里被用作值。”?