C ++在作为超类传递后使用重写方法

时间:2012-08-19 16:52:30

标签: c++ function methods virtual superclass

如果我有C ++函数/方法,例如:

getSound(Animal a){
  a.printSound();
}

然后传递一个Dog对象,该对象扩展了类Animal但覆盖了Animal的printSound()方法,有没有办法在printSound()内使用Dog的getSound() }?

我已尝试在printSound()类定义虚拟中创建Animal,但我仍然获得原始printSound()的输出。

提前致谢。

4 个答案:

答案 0 :(得分:6)

这是因为object-slicing,因为你接受了价值的论证。

通过引用接受它:

void getSound(Animal & a); //now reference

如果Animal::printSound()没有改变对象的状态,那么使它成为const成员函数(如果它不是const),然后通过const接受参数参考:

void getSound(Animal const & a); //now const reference

答案 1 :(得分:5)

使printSound虚拟是正确的。更改getSound的签名以使用Animal&const Animal&。通过Animal按值计算,您正在从Animal构建一个新的Dog,这只是一个Animal,而不是Dog

答案 2 :(得分:5)

当您致电getSound时,您将按值传递Animal。这意味着通过调用Dog的复制构造函数来创建Animal的副本。 Animal的复制构造函数构造Animal,而不是Dog。您可能希望通过引用传递:

getSound(Animal& a){
  a.printSound();
}

答案 3 :(得分:5)

除了一件事之外,你基本上已经做好了一切。

通过引用传递Animal对象

getSound(Animal &a);

或提供指向相关对象的指针。

getSound(Animal *a) {
    a->printSound();  //Mind the -> in this case.
}

要调用此功能,您可以这样:

Dog D;
getSound(&D);    //Passes a pointer to the function.

否则,你将构造一个“动物”类型的新对象,而不是真正“传递”一只狗。

实际上,你最好使用指针解决方案,否则在传递派生对象时会遇到问题,因为它会期望类型为Animal的对象并且不会满足于任何其他对象。 / p>