0

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

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

然后传递给它一个Dog扩展类Animal但覆盖动物方法的对象,有没有办法在里面printSound()使用狗?printSound()getSound()

我已经尝试printSound()Animal类定义中进行虚拟化,但我仍然得到原始printSound().

提前致谢。

4

4 回答 4

6

这是因为object-slicing,因为您按值接受参数。

通过引用接受它:

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

如果Animal::printSound()不改变对象的状态,则使其成为const成员函数(如果它不是 const 已经),然后通过const引用接受参数:

void getSound(Animal const & a); //now const reference
于 2012-08-19T16:58:17.777 回答
5

虚拟printSound化是正确的。将 的签名更改getSoundAnimal&const Animal&。通过取值,您正在从您Animal的 构建一个新的,而这只是一个,而不是一个。AnimalDogAnimalDog

于 2012-08-19T16:57:48.757 回答
5

当您调用时getSound,您正在传递Animal按值。这意味着Dog通过调用Animal的复制构造函数来制作 的副本。的Animal复制构造函数构造一个Animal,而不是一个Dog。您可能希望通过引用传递:

getSound(Animal& a){
  a.printSound();
}
于 2012-08-19T16:58:43.537 回答
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并且不会满足于其他任何东西。

于 2012-08-19T17:00:16.403 回答