只实例化派生类一次错误的 OOP



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

上下文:我正在为计算器应用程序奠定基础。我有一个Operator类,MultiplicationAddition等继承。我将 Operator 用作抽象基类,然后"计算器"包含一个Operator*的多态容器,并支持操作实例,因此它只需匹配 ID 即可在运算符上调用 evaluate

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.
另外,我

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

听起来像是使用 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,但您也可以使用普通函数)。当然,这仅在所有函数的签名相同时才有效,但从您的示例中似乎它们相同。

你在评论中说:

好吧,我很担心,因为似乎如果我正在定义一个对象,它应该是一个具有与每个实例关联的数据的东西。在这里,每个实例都是相同的,这让我很担心,但我看不到任何其他方法,因为我需要更改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;
      }
};

最新更新