如果我有一个 C++ 函数/方法,例如:
getSound(Animal a){
a.printSound();
}
然后传递给它一个Dog
扩展类Animal
但覆盖动物方法的对象,有没有办法在里面printSound()
使用狗?printSound()
getSound()
我已经尝试printSound()
在Animal
类定义中进行虚拟化,但我仍然得到原始printSound()
.
提前致谢。
如果我有一个 C++ 函数/方法,例如:
getSound(Animal a){
a.printSound();
}
然后传递给它一个Dog
扩展类Animal
但覆盖动物方法的对象,有没有办法在里面printSound()
使用狗?printSound()
getSound()
我已经尝试printSound()
在Animal
类定义中进行虚拟化,但我仍然得到原始printSound()
.
提前致谢。
这是因为object-slicing,因为您按值接受参数。
通过引用接受它:
void getSound(Animal & a); //now reference
如果Animal::printSound()
不改变对象的状态,则使其成为const
成员函数(如果它不是 const 已经),然后通过const
引用接受参数:
void getSound(Animal const & a); //now const reference
虚拟printSound
化是正确的。将 的签名更改getSound
为Animal&
或const Animal&
。通过取值,您正在从您Animal
的 构建一个新的,而这只是一个,而不是一个。Animal
Dog
Animal
Dog
当您调用时getSound
,您正在传递Animal
按值。这意味着Dog
通过调用Animal
的复制构造函数来制作 的副本。的Animal
复制构造函数构造一个Animal
,而不是一个Dog
。您可能希望通过引用传递:
getSound(Animal& a){
a.printSound();
}
你基本上做对了所有事情,除了一件事。
通过引用传递 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
并且不会满足于其他任何东西。