假设我有一个基类Animal
,一个类Cow
继承,一个Barn
类包含一个Animal
向量,让我们说动物类有虚拟函数scream()
,Cow
覆盖。
使用以下代码:
Animal.h
#ifndef _ANIMAL_H
#define _ANIMAL_H
#include <iostream>
using namespace std;
class Animal {
public:
Animal() {};
virtual void scream() {cout << "aaaAAAAAAAAAAGHHHHHHHHHH!!! ahhh..." << endl;}
};
#endif /* _ANIMAL_H */
Cow.h
#ifndef _COW_H
#define _COW_H
#include "Animal.h"
class Cow: public Animal {
public:
Cow() {}
void scream() {cout << "MOOooooOOOOOOOO!!!" << endl;}
};
#endif /* _COW_H */
Barn.h
#ifndef _BARN_H
#define _BARN_H
#include "Animal.h"
#include <vector>
class Barn {
std::vector<Animal> animals;
public:
Barn() {}
void insertAnimal(Animal animal) {animals.push_back(animal);}
void tortureAnimals() {
for(int a = 0; a < animals.size(); a++)
animals[a].scream();
}
};
#endif /* _BARN_H */
最后是main.cpp
#include <stdlib.h>
#include "Barn.h"
#include "Cow.h"
#include "Chicken.h"
/*
*
*/
int main(int argc, char** argv) {
Barn barn;
barn.insertAnimal(Cow());
barn.tortureAnimals();
return (EXIT_SUCCESS);
}
我得到了这个输出:
aaaAAAAAAAAAAGHHHHHHHHHH!!! ahhh...
我应该如何对此进行编码以获取MOOooooOOOOOOOO!!!
(以及继承Animal
希望scream()
的其他类别)?
答案 0 :(得分:12)
std::vector<Animal>
只能包含Animal
个对象,而不能包含Cow
个对象。
当您说barn.insertAnimal(Cow());
:
Cow()
。animal
是从该临时母牛复制构建的,因为您选择按值传递它。这个animal
是临时牛的Animal
部分的副本。这称为 object-slicing 。animal
复制构造的。现在你已经有了一头牛和另外两头动物,但你只想要一头牛!animal
已销毁,因为insertBarn
返回。这里有什么教训?不要按价值传递动物,也不要按价值存放动物。
运行时多态性需要一个间接级别。您可能需要std::vector<Animal*>
或std::vector<shared_ptr<Animal> >
或boost::ptr_vector<Animal>
。
答案 1 :(得分:2)
存储动物指针的细微修改应该有所帮助:
#ifndef _BARN_H
#define _BARN_H
#include "Animal.h"
#include <vector>
class Barn {
std::vector<Animal *> animals;
public:
Barn() {}
void insertAnimal(Animal *animal) {animals.push_back(animal);}
void tortureAnimals() {
for(int a = 0; a < animals.size(); a++)
animals[a]->scream();
}
};
int main(int argc, char** argv) {
Barn barn;
barn.insertAnimal(new Cow());
barn.tortureAnimals();
// should clean up barn contents here...
return (EXIT_SUCCESS);
}
答案 2 :(得分:2)
您正在进行按值传递,因此Cow
正在进入Animal
。
使用Animal *代替工作,虽然这有内存泄漏:
class Barn {
std::vector<Animal *> animals;
void insertAnimal(Animal *animal) {animals.push_back(animal);}
void tortureAnimals() {
for(int a = 0; a < animals.size(); a++)
animals[a]->scream();
}
};
int main(int argc, char** argv) {
Barn barn;
Cow *c = new Cow();
barn.insertAnimal(c);
barn.tortureAnimals();
/* delete them here... */
}