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

C++ Using an overriden method after passing as superclass

本文关键字:overriden 方法 超类 C++      更新时间:2023-10-16

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

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

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

我已经尝试在Animal类定义中使printSound()成为虚拟的,但我仍然得到原始printSound()的输出。

提前谢谢。

这是因为对象切片,因为您按值接受参数。

通过引用接受为:

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

如果Animal::printSound()没有更改对象的状态,则使其成为const成员函数(如果它还不是常量),然后接受const引用的参数为:

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

使printSound虚拟化是正确的。将getSound的签名更改为Animal&const Animal&。通过按值取一个Animal,您就从您的Dog构造了一个新的Animal,而这只是Animal,而不是Dog

当您调用getSound时,您正在按值传递Animal。这意味着通过调用Animal的复制构造函数来生成Dog的副本。Animal的复制构造函数构造的是Animal,而不是Dog。你可能想要通过参考:

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

除了一件事之外,您基本上都做对了。

通过引用传递动物对象

getSound(Animal &a);

或者提供一个指向有问题对象的指针。

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

要调用这个函数,你可以这样做:

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

否则,您将构造一个"Animal"类型的新对象,而不是真正"传递"一只狗。

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