3

这是我的代码

#include <iostream>
#include <vector>
#include <memory>
#include <tr1/memory> 
using namespace std;

class Animal {
  public:
    string name;
    Animal (const std::string& givenName) : name(givenName) {

    }

  };

class Dog: public Animal {
  public:
    Dog (const std::string& givenName) : Animal (givenName) {

    }
    string speak ()
      { return "Woof, woof!"; }
  };

class Cat: public Animal {
  public:
    Cat (const std::string& givenName) : Animal (givenName) {
    }
    string speak ()
      { return "Meow..."; }
  };

int main() {
    vector<Animal> animals;
    Dog * skip = new Dog("Skip");
    animals.push_back( skip );
    animals.push_back( new Cat("Snowball") );

    for( int i = 0; i< animals.size(); ++i ) {
        cout << animals[i]->name << " says: " << animals[i]->speak() << endl;
    }

}

这些是我的错误:

index.cpp: In function ‘int main()’:
index.cpp:36: error: no matching function for call to ‘std::vector<Animal, std::allocator<Animal> >::push_back(Dog*&)’
/usr/include/c++/4.2.1/bits/stl_vector.h:600: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Animal, _Alloc = std::allocator<Animal>]
index.cpp:37: error: no matching function for call to ‘std::vector<Animal, std::allocator<Animal> >::push_back(Cat*)’
/usr/include/c++/4.2.1/bits/stl_vector.h:600: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Animal, _Alloc = std::allocator<Animal>]
index.cpp:40: error: base operand of ‘->’ has non-pointer type ‘Animal’
index.cpp:40: error: base operand of ‘->’ has non-pointer type ‘Animal’

我想做的事:

我只想使用一个动态数据结构来遍历可能的 Animal 对象列表。

我正在尝试在 C++ 语法中学习这种多态性概念。

我熟悉 Java 和 PHP,但对 C++ 则不太熟悉。

更新:

我已经添加了其中一个答案提到的更改。http://pastebin.com/9anijwzQ

但是我收到有关 unique_ptr 的错误。我已经包含了内存。所以我不确定问题是什么。

http://pastebin.com/wP6vEVn6是错误消息。

4

2 回答 2

4

有两个问题。

首先,您的向量包含Animal对象,并且您试图用指向Animal派生类型的指针填充它。Animal并且Animal*不是同一类型,因此该操作通常不会编译。

Animal是没有办法speak()。如果要将派生类型的 推Animal入向量中,则会得到对象切片。你可以通过让你的向量持有智能指针来避免它Animal,例如std::vector<std::unique_ptr<Animal>>。但是你仍然需要给出Animal一个speak()虚拟方法。例如:

class Animal {   
 public:
  std::string name;
  Animal (const std::string& givenName) : name(givenName) {}
  virtual std::string speak () = 0;
  virtual ~Animal() {}
};

int main() {
  std::vector<std::unique_ptr<Animal>> animals;
  animals.push_back( std::unique_ptr<Animal>(new Dog("Skip")) );
  animals.push_back( std::unique_ptr<Animal>(new Cat("Snowball")) );
}

我在哪里制作Animal::speak()了一个纯虚拟方法并给出Animal了一个虚拟析构函数。

查看何时使用虚拟析构函数以及何时应该使用纯方法

于 2012-11-04T12:41:44.797 回答
2

你应该声明你的vectorvector<Animal*>好像你想推它Animal*一样skip。而且您确实需要其中的指针才能使用多态性。此外,您的基类动物还需要一个speak()方法 - 否则您不能在编译时只知道是Animal. 一旦进行了这些更改,它应该可以按预期工作。

于 2012-11-04T12:43:30.203 回答