2016-12-23 122 views
1

我有两个专门的对象继承对象的一般方法:有没有办法专门

class Food {}; 
class Fruit : public Food {}; 
class Vegetable : public Food {}; 

然后我将继承父类:

class Parent 
{ 
    virtual void say(Food* obj) { std::cout << "The object is food" << std::endl; } 
}; 

而且继承来自父母的课程。

class Child : public Parent 
{ 
    virtual void say(Fruit* obj) { std::cout << "The object is a fruit" << std::endl; } 
    virtual void say(Vegetable* obj) { std::cout << "The object is a vegetable" << std::endl; } 
}; 

我做的:

std::vector<Food*> basket; 
Fruit fruit = Fruit(); 
Vegetable vegetable = Vegetable(); 
basket.push_back(&fruit); 
basket.push_back(&vegetable); 

Child child = Child(); 

for (Food* food : basket) 
{ 
    child.say(food); 
} 

我想它打印“的对象是一种水果”,然后“的对象是蔬菜”,但它不工作: 我得到错误消息:参数1从'Food *'到'Fruit *'没有已知的转换。

有没有办法做到这一点,如果可能的话,不使用typeid,因为我听到它会导致开销。这里是一个在线编辑器代码:cpp.sh/27ekc

+1

不同的食物应该印刷自己多形态。然后你可以在'say'函数中调用该函数。 – NathanOliver

+4

在现实世界中,孩子知道她在吃什么。在OOP中,食物知道自己的名字。 – Arkadiy

+0

我认为问题在于,您无法调用期望多态的重载方法来确定要调用的方法。 –

回答

3

我认为合适的解决方案,这是以下几点:

class Food 
{ 
public: 
    virtual ~Food() = default; 
    virtual void say() const; 
}; 
class Fruit : public Food 
{ 
public: 
    void say() const override { std::cout << "The object is a fruit" << std::endl; } 
}; 
class Vegetable : public Food 
{ 
public: 
    void say() const override { std::cout << "The object is a vegetable" << std::endl; } 
}; 

class Parent 
{ 
public: 
    virtual ~Parent() = default; 
    virtual void say(const Food& obj) const { obj.say(); } 
}; 

class Child : public Parent {}; 

int main() 
{ 
    std::vector<Food*> basket; 
    Fruit fruit = Fruit(); 
    Vegetable vegetable = Vegetable(); 
    basket.push_back(&fruit); 
    basket.push_back(&vegetable); 

    Child child = Child(); 

    for (const Food* food : basket) 
    { 
     child.say(*food); 
    } 
} 

编辑: 按您的评论,它是根据你所说的健康是什么。 我把它解释为这些方针的东西:

class Food 
{ 
public: 
    virtual ~Food() = default; 
    virtual void say() const; 
    virtual int health() const; 
}; 
class Fruit : public Food 
{ 
public: 
    void say() const override { std::cout << "The object is a fruit" << std::endl; } 
    int health() const override { return 5; } 
}; 
class Vegetable : public Food 
{ 
public: 
    void say() const override { std::cout << "The object is a vegetable" << std::endl; } 
    int health() const override { return 10; } 
}; 

class Parent 
{ 
public: 
    virtual ~Parent() = default; 
    virtual void say(const Food& obj) const { obj.say(); } 
}; 

class Child : public Parent 
{ 
    int health; 

public: 
    void eat(const Food& obj) { health += obj.health(); } 
}; 

int main() 
{ 
    std::vector<Food*> basket; 
    Fruit fruit = Fruit(); 
    Vegetable vegetable = Vegetable(); 
    basket.push_back(&fruit); 
    basket.push_back(&vegetable); 

    Child child = Child(); 

    for (const Food* food : basket) 
    { 
     child.say(*food); 
     child.eat(*food); 
    } 
} 

有很多不同的方式来实现这一目标。

+0

非常感谢您的回答。但是,如果这样说会增加孩子的健康吗? – Talesseed

+0

@Talesseed:你也可以看看[访客模式](http://stackoverflow.com/documentation/design-patterns/4579/visitor-pattern/15127/visitor-pattern-example-in-c#t=201612232223221431311 )作为'Food'中添加方法的替代方法。 – Jarod42

+0

@ Jarod42谢谢,虽然不会在这里使用这种模式,因为它会复杂化一个需要非常简单的类。 – Talesseed