仅在一次糟糕的OOP实例化派生类?

时间:2016-02-19 05:24:31

标签: c++ oop inheritance instantiation

我有一个类结构,它只想让我的派生类只实例化一次。在我看来,这似乎是糟糕的OOP,因为多个实例是相同的并且没有用处,所以我应该替换它吗?

上下文 我正在为计算器应用程序构建基础。我有一个Operator类,MultiplicationAddition等继承自。{1}}。我使用Operator作为抽象基类,然后“计算器”保存Operator*的多态容器,并支持一个操作实例,因此它只能调用evaluate操作员只需匹配ID。

class Operator {
public:
    virtual int evaluate(int left, int right) = 0;

protected:
    const char ID;
    const int precedence;
};

class Multiplication : public Operator {
public:
    Multiplication() {
        ID = '*';
        precedence = 2;
    }
    virtual int evaluate(int left, int right) {
        return left * right;
    }
};

class Addition : public Operator {
public:
    Addition() {
        ID = '+';
        precedence = 1;
    }
    virtual int evaluate(int left, int right) {
        return left + right;
    }
};

// etc.

另外,我有点担心我是如何初始化常量的,但这不是我的主要问题。

2 个答案:

答案 0 :(得分:2)

这听起来像是使用std :: function:

的绝佳选择
class Operator{
    public: //just for demonstration
    const char ID;
    const int precedence;
    std::function<int(int,int)> func;
}

//in main:
Operator Multiplication{
    '*',
    2,
    [](int a, int b){return a*b;}
};

这里的想法是:

使Operator成为存储std :: function或函数指针的类。然后对类的实例进行加法,乘法等操作,并将每个实例传递给自己的std :: function(这里我使用了lambda,但你也可以使用普通函数)。当然,这只有在所有函数的签名相同的情况下才有效,但从你的例子来看它们似乎是相同的。

答案 1 :(得分:1)

你在评论中说:

  

我很关心,因为好像我正在定义一个对象,它应该是一个与每个实例相关的数据。在这里,每个实例都是相同的,这让我很担心,但由于我需要改变evaluate的实现,我无法看到任何其他方式。

是的,每个对象的数据都相同。这是一个很好的观察。当每个对象的数据相同时,最好将它们转换为static成员数据和/或在适当时通过函数virtual函数提供对它们的访问权。

这是您发布的代码的一个版本,用于删除成员数据并提供virtual函数来访问它们。这也消除了显式构造函数的需要。

class Operator {
   public:
      virtual int evaluate(int left, int right) = 0;
      virtual char getID() const = 0;
      virtual int getPrecedence() const = 0;
};

class Multiplication : Operator {
   public:
      virtual char getID() const
      {
         return '*';
      }

      virtual int getPrecedence() const
      {
         return 2;
      }

      virtual int evaluate(int left, int right) {
         return left * right;
      }
};

class Addition : Operator {
   public:
      virtual char getID() const
      {
         return '+';
      }

      virtual int getPrecedence() const
      {
         return 1;
      }
      virtual int evaluate(int left, int right) {
         return left + right;
      }
};