如果我有一个名为“动物”类和派生类“伯德:公共动物”,我可以创造一个鸟这两种方式:以不同的方式声明继承类的实例是否有区别?
Animal *sparrow = new Bird;
Bird *sparrow = new Bird;
两个预期编译罚款和工作。它们是否相同?我应该更喜欢一个吗?
如果我有一个名为“动物”类和派生类“伯德:公共动物”,我可以创造一个鸟这两种方式:以不同的方式声明继承类的实例是否有区别?
Animal *sparrow = new Bird;
Bird *sparrow = new Bird;
两个预期编译罚款和工作。它们是否相同?我应该更喜欢一个吗?
这条线本身并没有表现出差异。但是,假设Bird
声明Animal
上不存在的方法Fly
。你不会是能够做到:
Animal* a = new Bird;
a->Fly();
,另一方面,这是合法的:
Bird* b = new Bird;
b->Fly();
这里的区别是事实,C++是一种静态类型语言的结果。变量的静态类型是编译器在验证诸如方法调用之类的东西时所关心的。由于变量a
的静态类型为Animal
,它没有Fly
方法,因此编译器将不允许您对其调用Fly
(并非所有动物都可以飞行,因此您必须明确投射到Bird
: dynamic_cast<Bird*>(a)->Fly()
是合法的)。
表达式new Bird
将具有类型Bird*
。如果将派生类型的值分配给基础类型的变量,编译器将不会投诉(所有Bird
都是Animal
,所以它应该始终有效)。基本上,编译器上传Bird*
到Animal*
。相反是不正确的。并非所有的Animal
s都是Bird
s,所以你必须承担责任并明确地进行转换,并告诉编译器我知道该对象实际上是Bird*
。只有在这种情况下,编译器才会让您使用Bird
的特定功能。因此,一般来说,如果您需要使用Bird
特定成员,则最好使用Bird* b = new Bird;
。
我想我明白了。后续在我的脑海中清除它: 动物* A =新的动物; 动物* B =新鸟; 有了这些声明,A和B之间是否有区别? (在上面进行了一些修改之前询问的问题) – Jarred 2010-03-02 19:42:50
@Jarred:是的,由'A'指出的对象并不是一个真正的“鸟”,而由“B”指向的对象实际上仍然是一个“鸟”,而你只是决定不关心(因为你的功能同样适用于所有的动物,并且不依赖任何特定的鸟类)。由于'B'是一个'Bird',你可以再次成功地将它下传到'Bird *'并使用'Bird'特定的成员。将'A'投射到'Bird *'不会成功。 – 2010-03-02 19:48:21
非常感谢您的帮助。 – Jarred 2010-03-02 19:54:42