C++ 以这些不同的方式声明继承类的实例是否有差异?

C++ 以这些不同的方式声明继承类的实例是否有差异?,c++,C++,如果我有一个名为“Animal”的类和一个派生类“Bird:public Animal”,我可以通过以下两种方式创建一只鸟: Animal *sparrow = new Bird; Bird *sparrow = new Bird; 两者都编译得很好,并按预期工作。它们相等吗?我应该选择一个而不是另一个吗?这条线本身并没有显示出区别。但是,假设Bird声明了一个Fly方法,该方法在Animal上不存在。您将无法执行以下操作: Animal* a = new Bird; a->Fly();

如果我有一个名为“Animal”的类和一个派生类“Bird:public Animal”,我可以通过以下两种方式创建一只鸟:

Animal *sparrow = new Bird;
Bird *sparrow = new Bird;

两者都编译得很好,并按预期工作。它们相等吗?我应该选择一个而不是另一个吗?

这条线本身并没有显示出区别。但是,假设
Bird
声明了一个
Fly
方法,该方法在
Animal
上不存在。您将无法执行以下操作:

Animal* a = new Bird;
a->Fly();
另一方面,这是合法的:

Bird* b = new Bird;
b->Fly();
这里的区别是C++是静态类型语言的结果。当编译器验证方法调用之类的事情时,它关心的是变量的静态类型。由于变量
a
的静态类型是
Animal
,它没有
Fly
方法,编译器将不允许您对其调用
Fly
(并非所有动物都能飞,因此您必须显式地将其转换为
Bird
动态_cast(a)->Fly()
是合法的)


表达式
newbird
的类型为
Bird*
。如果将派生类型的值分配给基于类型的变量,编译器将不会抱怨(所有
Bird
s都是
Animal
s,因此它应该始终工作)。基本上,编译器将
Bird*
上传到
Animal*
。事实并非如此。并非所有的
Animal
s都是
Bird
s,因此您必须承担责任,明确地执行强制转换,并告诉编译器我知道该对象实际上是
Bird*
。只有在这种情况下,编译器才允许您使用特定于
Bird
的功能。因此,一般来说,如果需要使用特定于
Bird
的成员,最好使用
Bird*b=newbird

我想我明白了。一个在我脑海中清晰的后续行动:动物*A=新动物;动物*B=新鸟;有了这些声明,A和B之间有什么区别吗?(在上面的一些编辑之前提出的问题)@Jarred:是的,
A
指向的对象实际上不是一只
Bird
,而
B
指向的对象实际上仍然是一只
Bird
,你只是决定现在不在乎它是鸟(因为你的功能同样适用于所有动物,不依赖于鸟类的任何特定功能)。由于
B
是一只
Bird
,您可以再次成功将其向下转换为
Bird*
,并使用
Bird
特定成员。将
a
转换为
Bird*
将不会成功。非常感谢您提供的有用答案。