在c ++中遇到麻烦

时间:2013-07-18 14:16:45

标签: c++

我正在遍历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)等....

我收到以下错误:

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)

1 个答案:

答案 0 :(得分:8)

您的函数采用Animal by-value,而不是by-reference或pointer。我猜你有一个多态的层次结构,其中Animal是ABC,而Tiger是一个具体的派生类。

如果是这样,这段代码严重错误。通过按Animal按值计算,您slice the 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 &#34;其中一个virtual成员函数在大多数情况下都应该是析构函数&#34; :删除时需要这样做通过指向基类的指针实例化派生类,如:

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析构函数。