2016-12-23 158 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