这是我的代码
#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是错误消息.
解决方法:
有两个问题.
首先,您的向量包含Animal对象,并且您尝试使用指向Animal派生类型的指针填充它.动物和动物*的类型不同,因此通常不会编译操作.
第二,Animal没有方法说话().如果你要将衍生类型的Animal推送到向量中,你将获得object slicing.你可以通过让你的向量保持智能指针来避免它,例如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一个虚拟析构函数.
见when to use virtual destructors和when should a virtual method be pure.