C ++多态 - 使用不同签名

时间:2016-04-16 20:57:34

标签: c++ inheritance polymorphism

我正在用C ++进行生态系统模拟。其中有动物可以是食草动物或食肉动物。

食肉动物只吃其他食草动物,所以食肉动物eat()时,他们必须知道草食动物的方向。

草食动物只吃草,所以他们不需要知道任何方向,他们只是吃它们下面的什么。

class ANIMAL
{
public:
ANIMAL(...)
: ...
{
}
virtual ~ANIMAL()
{}

//does nothing, just stating that every animal must implement an Eat() method
virtual void Eat() = 0; 
};

class HERBIVORE : public ANIMAL
{
public:
HERBIVORE(...)
: ANIMAL(...)
{}
void Eat(CELL field[40][30], int x, int y);
};


class CARNIVORE : public ANIMAL
{
public:
CARNIVORE(...)
: ANIMAL(...)
{}

void Eat(CELL field[40][30], int x, int y, char direction);
};

功能定义如下:

void HERBIVORE::Eat(CELL field[40][30], int x, int y)
{
}

void CARNIVORE::Eat(CELL field[40][30], int x, int y, char direction)
{
}

使用virtual时,使用动态绑定,因此编译器会在运行时解析函数调用。但是我怎样才能编写这样的代码:

  if (dynamic_cast<CARNIVORE*>(this_animal))    //if carnivore
     this_animal->Eat(field, i, j, direction);

   if (dynamic_cast<HERBIVORE*>(this_animal))   //if herbivore
     this_animal->Eat(field, i, j);

没有收到此错误?

问题:

我收到错误:

  

&#39; ANIMAL ::吃&#39;:功能不带3个参数

     

&#39; ANIMAL ::吃&#39;:功能不带4个参数

它指的是不带参数的基类Eat()

2 个答案:

答案 0 :(得分:2)

您的类当前不会覆盖基类中的纯虚方法。任何虚拟覆盖都应具有与基类声明相同的签名。解决问题的一种简单方法是使所有重载都可以访问方向,具有如下定义:

void Eat(CELL field[40][30], int x, int y, char direction)
{
    ...
}

这种方式需要方向的重载有它,而不需要它的那些可以忽略它。此外,不需要dynamic_cast

答案 1 :(得分:1)

问题是你只使用动态强制转换来检查类。 this_animal仍然是指向ANIMAL的指针,因此没有Eat功能。

要解决您的问题,您必须使用动态强制转换直到结束:

 if (dynamic_cast<CARNIVORE*>(this_animal))    //if carnivore
     dynamic_cast<CARNIVORE*>(this_animal)->Eat(field, i, j, direction); // 4 args

 if (dynamic_cast<HERBIVORE*>(this_animal))   //if herbivore
     dynamic_cast<CARNIVORE*>(this_animal)->Eat(field, i, j);  // 3 args