是否可以从基类调用派生类的方法?例如;避免'切片'

时间:2013-03-25 15:32:59

标签: c++

假设有一些类,都来自名为Animal的基类:

Cat
Dog
Parrot
EveryAnimalInExistance

每个类都实现自己的抽象方法方法,例如:

attack()
defend()
hunt()
breed()

然后有一个名为

的方法
observeAnimal(Animal* everyAnimalInExistance)

如何从潜在的成千上万的动物中传递任何潜在的动物,只需致电

everyAnimalInExistance.hunt();

据我所知,在c ++中,对象将被“切片”,它会尝试调用基类自己的方法,并且需要进行类型转换才能调用正确的方法。

我无法确定RTTI在项目的每个环境中是否都可用,因为它的数量庞大且数量众多,是否有人可以启发我应采取的方法?

2 个答案:

答案 0 :(得分:4)

您的observeAnimal(Animal* everyAnimalInExistance)方法不执行切片,因为参数是通过指针接收的。

如果是指针或引用,将在动物园中正确调用虚函数:)。只有在按值传递everyAnimalInExistance时才会发生切片。

换句话说:

class Animal {
    virtual void hunt() = 0;
}

observeAnimal(Animal* everyAnimalInExistance)
{
    everyAnimalInExistance->hunt(); // correct
}
observeAnimal(Animal everyAnimalInExistance)
{
    everyAnimalInExistance.hunt(); // sliced, incorrect (call into base class)
}
observeAnimal(Animal& everyAnimalInExistance)
{
    everyAnimalInExistance.hunt(); // correct
}

std::vector<Animal> slice_and_dice;
// add animals to vector here (actually this vector will slice the animals
// when you add them)
slice_and_dice[0].hunt(); // incorrect, sliced

std::vector<Animal*> pointer_zoo;
// add animals to vector here
pointer_zoo[0]->hunt(); // correct

答案 1 :(得分:0)

直接回答你的问题...是的,(至少)有一种方法可以从基类Curiously Recurring Template Pattern调用派生类方法。实际上,这称为静态多态性