我很长时间以来一直是java开发人员。我确定我认为这是错误的方式。
但我有一类动物和一类狗。狗伸展动物,在我的主要部分,我制作一堆狗并将它们粘在动物的矢量中。
在对它们进行迭代时,我无法在最初为狗的对象上访问Dog特定方法。
我做错了什么?
动物
#include "Header.h"
class Animal {
std::string name;
int age;
public:
std::string getName(){ return name;}
virtual int getAge(){ return age;}
virtual int getRealAge();
Animal(std::string name, int age);
~Animal();
};
Animal::Animal(std::string name, int age){
this->name = name;
this->age = age;
}
int Animal::getRealAge() {
return this->age*100/2;
}
Animal::~Animal() {
}
狗
#include "Header.h"
class Dog : public Animal {
public :
Dog(std::string name, int age);
~Dog();
int getAge();
};
Dog::Dog(std::string name, int age) : Animal::Animal(name, age) {
}
Dog::~Dog(){
}
int Dog::getAge() {
return Animal::getAge()*7;
}
主要
#include "Header.h"
using namespace std;
int main() {
cout << "Hello, World!" << endl;
// I make a bunch of Dogs
Dog tmp0("Ellie", 1);
Dog tmp5("sam", 2);
Dog tmp4("lindsay", 3);
Dog tmp3("shilo", 4);
Dog tmp2("rex", 5);
Dog tmp1("bob", 6);
Animal tmp00("nick", 11);
vector<Animal*> animals;
animals.push_back(&tmp0); // Dog is-an Animal
animals.push_back(&tmp1);
animals.push_back(&tmp2);
animals.push_back(&tmp3);
animals.push_back(&tmp4);
animals.push_back(&tmp5);
animals.push_back(&tmp00); //new
for(auto &animal : animals){
Animal *tmp = NULL;
if (typeid(animal) == typeid(Animal)){
cout << "Found animal" << endl;
}else{
cout << "Found animal" << endl;
cout << animal->getName() << " is " << animal->getAge() << endl;
}
}
return 0;
};
输出
Found Dog
Ellie is 1
Found Dog
bob is 6
Found Dog
rex is 5
Found Dog
shilo is 4
Found Dog
lindsay is 3
Found Dog
sam is 2
Found Dog
nick is 11
但他们都应该乘以7.
修改
我将虚拟类型添加到上面Animal类中的方法,并向我的vector添加了一个类型为Animal的Object。
但是,在main中的for循环中,对象也返回类型dog。
答案 0 :(得分:3)
您需要将getAge
设为虚拟功能。
答案 1 :(得分:2)
我不确定,你的意思是in the for loop in the main, the object returns as type dog as well
。如果你的意思是,typeid(animal) == typeid(Animal)
的条件永远不会成立,那么它应该如何工作,因为typeid将返回大多数派生的动态类型的对象。
而不是typeid
我会建议您编写一个多态函数,它将接受最合适的对象。 I. e。你可以写
void animal_test(Dog& dog)
{
/* this will be called when argument is Dog or its ancestor… */
}
void animal_test(Animal& any)
{
/* this will be called in all other cases */
}
对于虚函数,这是Java和C ++之间的主要区别,因为C ++函数默认情况下不是虚函数。如果你的函数不是虚函数(至少在类层次结构中的某个点,比用于调用该函数的对象的指针更高),将调用哪个函数仅取决于指针类型。
答案 2 :(得分:1)
让getAge虚拟化是一个理智的选择,但它至少值得注意的是你可以通过替换来获得你想要的行为...
if (typeid(animal) == typeid(Animal)){
cout << "Found animal" << endl;
}else{
cout << "Found animal" << endl;
cout << animal->getName() << " is " << animal->getAge() << endl;
}
...与...
if (Dog* p = dynamic_cast<Dog*>(&animal))
{
// inside here, p is known to be a Dog* at compile time, so
// getAge() is statically dispatched to Dog::getAge
cout << "Found animal/dog" << endl;
cout << p->getName() << " is " << p->getAge() << endl;
}else{
cout << "Found animal" << endl;
}
这个dynamic_cast<>
在C ++中会被认为是一种反模式(对于每个使用getAge()
的客户端代码网站来说,它必须知道派生类&#39;具体而言,virtual
函数是更好的方法。