在运行时选择派生类并运行唯一的类方法

时间:2021-01-08 19:19:33

标签: c++ oop derived-class variant

是否可以在运行时选择派生类,然后执行具有不同参数编号/类型的方法?例如,我们有基类 Fruit

class Fruit{
    public:
        int weight;
        Fruit(int);
};

Fruit::Fruit(int w) : weight(w){};

带有派生类 AppleOrange

class Apple : public Fruit {
    public:
        void eat(int);
        Apple(int);
};

Apple::Apple(int w) : Fruit(w){};

void Apple::eat(int amount){
    weight -= amount;
};
class Orange : public Fruit {
    public:
        void eat(int, bool);
        Orange(int);
};

Orange::Orange(int w) : Fruit(w){};

void Orange::eat(int amount, bool peel){
    if (peel){
         weight /= 10;
    }
    weight -= amount;
};

它们都有 eat 方法,但参数不同。如何选择在运行时创建哪个派生类然后执行 eat

int main(){
    // read input i.e. (apple, 5) or (orange, 2, true)
    // create either apple or orange 
    // eat it
}

2 个答案:

答案 0 :(得分:0)

使用类似于 command pattern 的方法。通过构造函数传递不同的参数,并在需要时执行 eat 方法的不同实现。像这样:

class Fruit {
  public:
  int weight;
  Fruit(int);
  virtual void eat() = 0;
};

Fruit::Fruit(int w) : weight(w){};

class Apple : public Fruit {
  public:
  void eat() override;
  Apple(int, int);
  int amount;
};

Apple::Apple(int w, int a) : Fruit(w){};

void Apple::eat() { weight -= amount; };

class Orange : public Fruit {
  public:
  void eat() override;
  Orange(int, int, bool);
  int amount;
  bool peel;
};

Orange::Orange(int w, int a, bool p) : Fruit(w), amount{a}, peel{p} {};

void Orange::eat() {
  if (peel) {
    weight /= 10;
  }
  weight -= amount;
};

答案 1 :(得分:0)

多态的目标是不知道您正在访问的对象的具体细节。在这种情况下,由于 Orange 具有 peel 没有的额外 Apple 操作,因此我会采用更类似的方法:

class Peelable {
public:
    virtual void peel() = 0;
};

class Fruit {
public:
    int weight;

    Fruit(int weight) : weight(weight) {}
    virtual ~Fruit() = default;

    void eat(int amount) { weight -= amount; }
};

class Apple : public Fruit {
public:
    Apple(int weight) : Fruit(weight) {}
};

class Orange : public Fruit, public Peelable {
public:
    Orange(int weight) : Fruit(weight) {}
    void peel() override { weight /= 10; }
};

int main() {
    // read input i.e. (apple, 5) or (orange, 2, true)

    // create either apple or orange 
    Fruit *f = new /* Apple(5), Orange(2), ... */;

    // eat it
    Peelable *p;
    if ((p = dynamic_cast<Peelable*>(f)) && shouldPeel) {
        p->peel();
    }
    f->eat();

    delete f;
}
相关问题