如果我没记错的话,在Java中,我们可以将子类传递给具有超类的函数.代码看起来像这样.
// Assume the classes were already defined, and Apple // and Pineapple are derived from Fruit. Fruit apple = new Apple(); Fruit pineapple = new Pineapple(); public void iHaveAPenIHaveAn(Fruit fruit) { ... } // :) ... public static void main(String[] arg) { iHaveAPenIHaveAn(apple); // Uh! Apple-pen. iHaveAPenIHaveAn(pineapple); // Uh! Pineapple-pen. }
然而,在C++中,我注意到,从这里,你需要使用基类的引用变量(那是适当的期限?),而不是基类的常规变量.
假设你有两个类:一个基类A
和一个A
派生类B
.
class A { ... }; class B : A { ... };
如果我们有一个neverGonna()
接受类A
参数的函数,那么为什么函数看起来像这样:
void neverGonna(A& a) { ... } ... B giveYouUp; neverGonna(giveYouUp);
而不是这个?
void neverGonna(A a) { ... } ... B letYouDown; neverGonna(letYouDown);
它背后的原因是什么?
Java中的对象由指针引用.(Java称它们为"引用".)如果Apple a;
用Java 编写,变量a
实际上是一个指针,指向Apple
内存中的某个对象.但是在C++中,如果你编写,Apple a;
那么变量a
包含整个Apple
对象.要获取指针,您需要显式声明a
为指针变量,如in Apple* a;
或reference,如Apple& a;
.
函数参数也是如此.在Java中,如果发送一个Apple
需要a Fruit
(假设是Apple
它的子类Fruit
)的方法,实际发送的是指针,对象本身存储在其他地方.
在C++中,对象本身被复制并发送给函数.但是,如果函数需要一个Fruit
对象,并且发送一个Apple
带有一些额外成员变量的对象,则该函数Apple
将不适合该函数必须接收的空间Fruit
.必须将Apple
对象转换为Fruit
对象,并删除任何特定于苹果的额外内容.这称为对象切片.