2016-12-23 6 views
1

継承されたオブジェクトの一般的な方法を専門にする方法はあります:私は2つの特殊なオブジェクトを持って

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

そして継承:次に

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

私は継承される親クラスを持っています親からのクラス。

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); 
} 

「オブジェクトは果物である」とし、「オブジェクトは、植物である」が、それは動作しません: 私を得ますエラーメッセージ:「Food *」から「Fruit *」への引数1の既知の変換はありません。

私はそれがオーバーヘッドの原因と聞いたので、可能であれば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); 
    } 
} 

EDIT:あなたのコメントどおり 、それはあなたが健康で何を意味するかに基づいています。 私はこれらの線に沿って何かとしてそれを解釈:

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:[visitor-pattern](http://stackoverflow.com/documentation/design-patterns/4579/visitor-pattern/15127/visitor-pattern-example-in-c#t=201612232223221431311)もご覧ください。 )を 'Food'にメソッドを追加する代わりに使用します。 – Jarod42

+0

@ Jarod42ありがとう、非常にシンプルである必要があるクラスを複雑にするので、このパターンはここでは使用しません。 – Talesseed

関連する問題