繁体   English   中英

如何设计派生类交互的灵活C ++程序?

[英]How to design a flexible C++ program in which derived classes interact?

我希望这里的专家对以下问题有意见。 我想设计一个程序,其中来自不同基类的派生类彼此交互。 为了阐明我的观点,我构建了一个示例。

想象一下我试图去动物园。 在这个动物园里,我们有动物,有水果,这是我的基础课。 只有在运行时,我们才能知道我们拥有哪些动物以及哪些果实。 假设我有一只猴子和一根香蕉。

如何让这只猴子以优雅的方式食用香蕉,而吃香蕉只是这只猴子的一项非常独特的技能? 请注意,我不需要通用的eat函数,因为在设计中我需要完全自由地实现派生动物可以执行的动作。

这是随附的示例:

#include <string>
#include <iostream>

class cfruit
{
};

class cbanana : public cfruit
{
};

class canimal
{
};

class cmonkey : public canimal
{
  public:
    int eatbanana(cbanana *) { std::cout << "BURP" << std::endl; }
};

int main()
{
  cfruit  *fruit;
  canimal *animal;

  // on runtime the animal and the fruit is decided, so we have to 
  // initialize it on the base pointer

  // assume we get a monkey and a banana
  fruit  = new cbanana();
  animal = new cmonkey();

  // now, we would like our monkey to eat a banana, which we cannot do...
  // UNLESS... we do something really UGLY
  static_cast<cmonkey *>(animal)->eatbanana(static_cast<cbanana *>(fruit));

  return 0;
}

您在问我们一种“优雅地”违反李斯科夫原则的方法。

当你操纵妈妈级,你应该认为是背后实例化具体的派生类。

这称为不良设计,编码有异味。

如果您的班级确实是猴子,并且您想让它吃香蕉:那么您不应该像猴子那样操纵它。

无论如何,寻找解决方案的途径可以从这种方式开始:正如您所解释的,动物及其果实之间存在隐式链接。 您可以创建一个班餐,其目标是明确管理此链接。

struct Meal
{
    virtual void consume() = 0;
}

Meal* factoryCookMonkeyMeal(Monkey& monkey, Banana& banana)
{
    return new MealMonkey(monkey,banana);    
}

struct MealMonkey : public Meal
{
    Monkey& monkey; 
    Banana& banana;

    virtual void consume(){ monkey.eat_banana(banana);};
}

Meal* factoryCookBirdMeal(Bird& bird, Cherry& cherry)
{
    return new MealBird(bird,cherry);
}

struct MealBird : public Meal
{
    Bird& bird;
    Cherry& cherry;

    virtual void consume(){  bird.eat_cherry(cherry);};
}

但是,您不能准确地告诉我们确定动物和水果的方式...所以这无济于事...因为正是这种选择知道了调用好的factoryMethod所必须使用的信息,从而创建了适当的一餐。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM