我是C ++的新手,因为我从Java / C#转换。有人可以解释为什么我的代码没有像我认为的那样工作。我有一个简单的Animal类层次结构,然后由Dog和Cat继承。类之间的唯一区别是它们的虚方法toString()/,它显然根据/上调用的类返回一个字符串。好的,所以我输入信息并用cin创建类并将它们推送到动物矢量中。但是当我试图调用它们的toString()时,我得到了基于toString()的结果,而不是覆盖它的结果。这是以下代码:
#include <iostream>
#include <vector>
#include "animal.h"
#include "cat.h"
#include "dog.h"
using namespace std;
int main()
{
vector<Animal> animals;
string type;
string name;
int age;
int weight;
while(cin >> type){
cin >> name >> age >> weight;
if(type == "dog"){
animals.push_back(Dog(name, age, weight);
}
else {
animals.push_back(Cat(name, age, weight);
}
}
for(vector<Animal>::iterator iter = animals.begin(); iter != animals.end();
iter++){
cout << iter -> toString() << endl;
}
return 0;
}
但是在我做了一些谷歌搜索后,我发现了一个建议,我应该使用指针,因为有一些叫做对象切片的东西。那么我的代码变成了这个:
#include <iostream>
#include <vector>
#include "animal.h"
#include "cat.h"
#include "dog.h"
using namespace std;
int main()
{
vector<Animal*> animals;
string type;
string name;
int age;
int weight;
while(cin >> type){
cin >> name >> age >> weight;
if(type == "dog"){
Dog tempDog(name, age, weight);
animals.push_back(&tempDog);
}
else {
Cat tempCat(name, age, weight);
animals.push_back(&tempCat);
}
}
for(vector<Animal*>::iterator iter = animals.begin(); iter != animals.end();
iter++){
cout << iter -> toString() << endl;
}
return 0;
}
现在我收到编译错误,建议我应该使用&#39; - &gt;&#39;;
我在这里也是一个问题,我想问一下。有没有办法覆盖.cpp文件中的虚方法,而不是定义类的头文件。我最近在c ++中进入了oop,我的想法是在头文件中我只定义了类成员的原型,并在不同的.cpp文件中执行。
答案 0 :(得分:0)
cout << iter -> toString() << endl;
尝试调用*iter
类型的成员函数。由于*iter
是Animal*
,因此它没有任何成员函数。你需要做的是获取迭代器的值,然后用->
调用它的成员函数,如
cout << (*iter)->toString() << endl;
另请注意,如果您可以访问C ++ 11或更高版本,则可以使用基于范围的for循环,例如
for (auto& e : animals)
cout << e->toString() << "\n";
我也更改为"\n"
而不是endl
,因为通常您不需要调用flush
,因此您只应在知道自己需要时才这样做。
您的代码中也有未定义的行为。
if(type == "dog"){
Dog tempDog(name, age, weight);
animals.push_back(&tempDog);
}
是要在向量中添加指向自动对象的指针。当你离开if块时自动对象被自动销毁。在它被销毁之后,你现在有一个指向不再存在的对象的指针。快速解决方法是使用new
动态分配对象,如
if(type == "dog"){
Dog* tempDog = new Dog(name, age, weight);
animals.push_back(tempDog);
}
现在向量中的指针仍然有效。不幸的是,现在你需要记住在完成它们之后删除所有这些指针。您无需进行手动内存管理,而是可以使用std::unique_ptr
或std::shared_ptr
等智能指针来管理内存。