c ++错误没有匹配功能

时间:2012-11-04 12:40:31

标签: c++ vector polymorphism

这是我的代码

#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是错误消息。

2 个答案:

答案 0 :(得分:4)

有两个问题。

首先,你的向量包含Animal个对象,你试图用指向Animal派生类型的指针填充它。 <{1}}和Animal的类型不同,因此通常不会编译操作。

其次,Animal*没有方法Animal。如果您要将派生类型的speak()推送到向量中,您将获得object slicing。您可以通过让向量保持指向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()提供了一个虚拟析构函数。

请参阅when to use virtual destructorswhen should a virtual method be pure

答案 1 :(得分:2)

如果您想vector vector<Animal*>,请将Animal*声明为skip。并且你确实需要指针,以便能够使用多态。此外,您的基类动物还需要speak()方法 - 否则您无法在编译时只知道Animal的对象上调用它。一旦做出这些改变,它应该按照您的预期工作。