我有一个类结构,它打算只让我的派生类实例化一次。在我看来,这就像糟糕的 OOP,因为多个实例是相同的并且没有任何用途,所以我应该替换它吗?
上下文:我正在为计算器应用程序奠定基础。我有一个Operator
类,Multiplication
、Addition
等继承。我将 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;
}
};