假设我有一个基类Animal和一个包含Animal向量的Barn类,其中Cow类继承了这个基类,再假设Animal类有一个Cow重写的虚拟函数scream()。
使用以下代码:
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()成为的类)呢?
发布于 2010-06-16 08:16:56
稍微修改一下,存储指向动物的指针应该会有所帮助:
#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);
}发布于 2010-06-16 08:11:43
std::vector<Animal>只能包含Animal对象,不能包含Cow对象。
下面是当你说barn.insertAnimal(Cow());的时候会发生什么
Cow类型的临时对象是通过Cow().
animal是从该临时cow复制构造的,因为您选择按值传递它。此animal是临时奶牛的Animal-part的副本。这称为object-slicing.
animal复制构造的。现在您已经有了一头母牛和两个额外的动物,但是您只需要一头母牛!
animal被销毁,因为insertBarn返回。
这里的教训是什么?不要按值传递动物,也不要按值存储动物。运行时多态性需要一定程度的间接性。您可能需要一个std::vector<Animal*>、std::vector<shared_ptr<Animal> >或boost::ptr_vector<Animal>。
发布于 2010-06-16 08:24:49
您正在进行按值传递,因此将把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... */
}https://stackoverflow.com/questions/3049952
复制相似问题