C++ 获取要调用的继承函数的函数
假设我有一个基类C++ 获取要调用的继承函数的函数,c++,inheritance,C++,Inheritance,假设我有一个基类Animal,一个类Cow从中继承,一个Barn类包含一个Animal向量,假设Animal类有一个虚拟函数cream(),它覆盖了Cow 使用以下代码: 动物 #ifndef _ANIMAL_H #define _ANIMAL_H #include <iostream> using namespace std; class Animal { public: Animal() {}; virtual void scream() {cout <&
Animal
,一个类Cow
从中继承,一个Barn
类包含一个Animal
向量,假设Animal类有一个虚拟函数cream()
,它覆盖了Cow
使用以下代码:
动物
#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 */
我应该如何编码才能得到mooooooo
(以及继承Animal
的其他类所希望的尖叫()
对象?Astd::vector
只能包含Animal
对象,而不能包含Cow
对象
下面是当您说barn.insertAnimal(Cow())时发生的情况代码>:
Cow类型的临时对象是通过计算Cow()
创建的
参数animal
是从临时奶牛复制而来的,因为您选择按值传递它。该动物
是临时奶牛的动物
的副本。这称为对象切片
向量中的下一个元素是由参数animal
构建的copy。现在你已经有了一头牛和另外两头动物,但你只想要一头牛李>
参数animal
被销毁,因为insertBarn
返回
临时cow将被销毁,因为求值已达到行末尾的分号(更准确地说,完整表达式的求值已完成)
这里的教训是什么?不要按价值传递动物,也不要按价值储存动物。
运行时多态性需要一定级别的间接寻址。您可能需要一个std::vector
或std::vector
或boost::ptr_vector
存储动物指针的轻微修改应有助于:
#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);
}
\ifndef\u BARN\H
#定义谷仓
#包括“Animal.h”
#包括
班仓{
性病:媒介动物;
公众:
谷仓(){}
void insertAnimal(动物*动物){动物。推回(动物);}
(动物){
对于(int a=0;a尖叫();
}
};
int main(int argc,字符**argv){
谷仓;
谷仓。插入动物(新牛());
虐待动物();
//应该清理一下谷仓里的东西。。。
返回(退出成功);
}
您正在通过值传递,因此奶牛
正在被制作成动物
相反,使用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... */
}
class仓库{
性病:媒介动物;
void insertAnimal(动物*动物){动物。推回(动物);}
(动物){
对于(int a=0;a尖叫();
}
};
int main(int argc,字符**argv){
谷仓;
Cow*c=新Cow();
谷仓动物(c);
虐待动物();
/*在这里删除它们*/
}
澄清一下:你的向量需要持有指针,因为当你持有实际对象时,它会遇到切片问题。我的Cow
也会退化为一只Animal
?有点错误:你的Cow
的Animal
部分被复制到向量中。我建议不要使用指针向量。而是使用boost:ptr_vector这是一个专门设计用来保存指针并管理其寿命的容器。或者使用一个指向动物的共享指针向量。嘿:boost::ptr_vector
教程甚至使用了“动物”层次结构作为示例(尽管没有奶牛):呃。。你必须删除这些。也许是boost::ptr_vector
或std::vector
,或者你必须有一个for循环来删除这些东西……@Billy ONeal,是的,我在一篇评论中编辑了这样的内容。boost指针是一种更好的方法,但需要对示例进行更多的编辑。我觉得这会让人明白如何部署多态性。事实上,先折磨动物,然后干脆忘记它们是相当残忍的。。。释放可怜的生物@马丁:实际上,<代码>和COW()(代码)>在标准C++中是非法的,因为地址运算符只能应用于LValk。即使某些变态的编译器允许,在barn.movests()行中也不存在临时cow代码>不再!很好的示例代码!尖叫的奶牛会引起一个有趣的阅读:)比foo和bar好多了
#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...
#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);
}
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... */
}