动态强制转换C+的奇怪问题+; 我只是C++的新手,做了一个实现继承的小项目。基本上可以概括如下: //.h file class Food{ public: Food(); virtual ~Food(); }; class Animal{ public: Animal(); virtual ~Animal(); virtual void eat( Food f); }; class Meat : public Food{ public: Meat(); ~Meat(); }; class Vegetable : public Food{ public: Vegetable(); ~Vegetable(); }; class Carnivore : public Animal{ public: Carnivore(); ~Carnivore(); void eat(Food f); }; //.cpp file Food::Food() { do something; } Food:~Food() { do something; } Animal::Animal() { do something; } Animal::~Animal() { do something; } Meat::Meat() { do something; } Meat::~Meat() { do something; } Vegetable::Vegetable() { do something; } Vegetable::~Vegetable() { do something; } Carnivore::Carnivore() { do something; } Carnivore::~Carnivore() { do something; } void Carnivore::eat(Food f) { Meat* m = dynamic_cast<Meat*>(&f); if(m != 0) cout << "can eat\n"; else cout << "can not eat\n"; } //main.cpp int main() { Animal* a; Food* f; Meat m; Vegetable v; Carnivore c; a = &c; f = &v; a->eat(*f); f = &m; a->eat(*f); return 1; }

动态强制转换C+的奇怪问题+; 我只是C++的新手,做了一个实现继承的小项目。基本上可以概括如下: //.h file class Food{ public: Food(); virtual ~Food(); }; class Animal{ public: Animal(); virtual ~Animal(); virtual void eat( Food f); }; class Meat : public Food{ public: Meat(); ~Meat(); }; class Vegetable : public Food{ public: Vegetable(); ~Vegetable(); }; class Carnivore : public Animal{ public: Carnivore(); ~Carnivore(); void eat(Food f); }; //.cpp file Food::Food() { do something; } Food:~Food() { do something; } Animal::Animal() { do something; } Animal::~Animal() { do something; } Meat::Meat() { do something; } Meat::~Meat() { do something; } Vegetable::Vegetable() { do something; } Vegetable::~Vegetable() { do something; } Carnivore::Carnivore() { do something; } Carnivore::~Carnivore() { do something; } void Carnivore::eat(Food f) { Meat* m = dynamic_cast<Meat*>(&f); if(m != 0) cout << "can eat\n"; else cout << "can not eat\n"; } //main.cpp int main() { Animal* a; Food* f; Meat m; Vegetable v; Carnivore c; a = &c; f = &v; a->eat(*f); f = &m; a->eat(*f); return 1; },c++,C++,你正在将食物的价值传递给进食功能。要使多态性发挥作用,您需要通过引用或指针进行传递: void Carnivore::eat(Food* f) { Meat* m = dynamic_cast<Meat*>(f); if(m != 0) cout << "can eat\n"; else cout << "can not eat\n"; } (通过指针:) void肉食动物::吃(食物*f) { 肉*m=动态_铸造(f); 如果(m!=0)不能当你有

你正在将食物的价值传递给进食功能。要使多态性发挥作用,您需要通过引用或指针进行传递:

void Carnivore::eat(Food* f)
{
 Meat* m = dynamic_cast<Meat*>(f); 
 if(m != 0) cout << "can eat\n";
 else cout << "can not eat\n";
}
(通过指针:)

void肉食动物::吃(食物*f)
{
肉*m=动态_铸造(f);

如果(m!=0)不能当你有这样一个函数时:

void Carnivore::eat(Food f)
它按值获取其参数。这意味着创建了所提供对象的副本

在本例中,您指定的是一个类型
食品
,因此您最终得到了一个
食品
对象。没有神奇的多态性,什么都没有。只有一个bog标准
食品
对象

这就是所谓的切片;请继续查找这个术语,因为网上有很多关于它的东西

但简而言之,您可以通过接受对现有多态对象的引用来保持多态性的使用:

void Carnivore::eat(Food& f)
另外,下次请发布一个最小的测试用例。这是一个巨大的代码片段


祝您学习顺利。

对象切片是导致实现中出现问题的原因

您的
eat()
函数应该引用
Food
或指向
Food
的指针,如下所述:

virtual void eat(Food & f);

//usage
Meat meat;
animal.eat(meat);


这就是所谓的“切片问题”。您的函数正在获取您传递的对象的副本。副本是由基类型的复制构造函数生成的,并且您为派生类所做的任何专门化都将丢失。

C++的运行时多态性(也称为虚拟函数调用/虚拟分派)要求通过指向基类的指针或引用来调用函数。在这里,eat函数通过value获取一个Food参数,该参数复制或切片*f值的一部分,并创建一个新的
Food
对象。此类对象不能通过
dynamic_cast
进行浇铸,因为
Meat
部分已被切断。只需更改为
肉食动物::吃(const Food&f)
而且它会起作用。

@Tomalak-1:好的,问题没有明确说明,但是如果你读了代码就很清楚了。@AutoCompulated:我同意,这就是为什么你会发现我在下面列出了一个写得很好的答案。@Tuan:我很高兴看到有人在没有动态分配的情况下使用多态性!@Matthieu:哦,是的,不错吧!?这是怎么回事“不是真正的问题”?投票重新开放。这不是真正的解释。:)
virtual void eat(Food & f);

//usage
Meat meat;
animal.eat(meat);
virtual void eat(Food * pf);

//usage
Meat meat;
animal.eat(&meat); //note &