2

我正在遍历一个Animal对象列表(其中包含 3 或 4 种不同类型的对象,它们都是从 子类化的Animal):

foreach (Animal entry, animalList)
{

    switch(entry.animalType)
    {
    case Animal::tiger:
        qDebug() << static_cast<Tiger>(entry).tigerString;
        break;
    }
}

这给了我以下错误:

no matching function for call to 'Tiger::Tiger(Animal&)'

所以我尝试了:

static_cast<Tiger*>(entry).tigerString;

这给了我以下错误:

invalid static_cast from type 'Animal' to type 'Tiger*'

所以最后我决定改成entry这样的指针类型:

foreach (Animal* entry, animalList)ETC....

我收到以下错误:

cannot convert 'const value_type {aka const Animal}' to 'Animal*' in initialization

我在这里错过了什么吗?我绝对需要得到tigerString哪个是特定于子类的字符串Tiger

我应该做什么?

更新 请参阅以下内容(代码已被剥离以保持清洁):

std::list<Animal*> animalList;

Tiger *myTiger = new Tiger();
myTiger->animalType= Animal::tiger;
myTiger->tigerString= "I am a tiger";

animalList.push_back(myTiger, animalList);

foreach (Animal* entry, animalList)
{
    Tiger* tiger = dynamic_cast <Tiger*> (entry);

    if (tiger)
    {
        // It is a tiger
    }
    else
    {
        // it is NOT a tiger
     }
}

我在第一行收到以下错误foreach loop

cannot dynamic_cast 'animal' (of type 'class Animal*') to type 'class Tiger*' (source type is not polymorphic)

4

1 回答 1

8

您的函数采用Animal按值,而不是按引用或指针。我猜你设计了一个多态层次结构,其中AnimalABCTiger是一个具体的派生类。

如果是这样,则此代码肯定是错误的。通过Animal取值,您将 object 切片,剩下的只是一个Animal. 一切Tiger都过去了。

当你做了

static_cast<Tiger*>(entry).tigerString;

您试图将非指针转换为指针。那永远行不通。将您的函数更改为Animal按引用(或指针)。

您还试图使用错误的演员表。当从基础到派生的多态对象时,您应该使用dynamic_cast,而不是此处。static_cast

做这个:

foreach (Animal* animal)
{
  Tiger* tiger = dynamic_cast <Tiger*> (animal);
  if (tiger)
  {
    // It is a tiger
  }
  else
  {
    // it is NOT a tiger
  }
}

最后,从评论中发现您实际上并没有使用多态类型。多态类是在基类中至少有一个virtual成员函数的类。在大多数情况下,其中一个virtual成员函数应该是析构函数1

class Animal
{
public:
  virtual ~Animal(){};
};

...即使它是微不足道的(没有实现)。在许多情况下,这甚至可能是唯一 virtual的成员函数,这很好。


1 virtual在大多数情况下,其中一个成员函数应该是析构函数”:当您通过指向基类的指针删除派生类的实例时,需要这样做,如下所示:

class Animal
{
public:
  virtual ~Animal() {}
};

class Tiger : public Animal
{
};

int main()
{
  Animal* a = new Tiger;
  delete a; // Without the virtual destructor, this would evoke Undefined Behavior
}

经验法则:如有疑问,virtual请向所有多态基类添加析构函数。

于 2013-07-18T14:22:49.897 回答