多态运算符(更新(c++))



我正试图在c++类中编写命题逻辑公式。公式可以是:

一个变量
  1. 公式的否定
  2. 两个由连接符
  3. 连接的公式

我无法定义一种方法将这三种不同的结构定义到一个类中,所以我决定将它们声明为不同的子类。我遇到的问题是,当声明操作符时,它们似乎没有正确地覆盖标准操作符。,,返回bool值而不是shared_ptr

解决:只是在基类中使用shared_ptr来避免任何切片。

#include <iostream>
#include <memory>
using namespace std;
// {0, 1, 2}
// {and, or, implies}
class formula
{
shared_ptr <formula> F;
public:
formula ()
{}
formula (shared_ptr <formula> f)
{
F = f;
}
formula (formula* f)
{
F = shared_ptr <formula> (f);
}

virtual bool evaluate ()
{
return F -> evaluate ();
}
virtual string type ()
{
return F -> type ();
}
shared_ptr <formula> address ()
{
return F;
}
virtual void assign (bool b)
{
F -> assign (b);
}
formula operator&& (formula f);
formula operator|| (formula f);
formula operator>> (formula f);
formula operator! ();
};
class variable : public formula
{
bool value;
public:
void assign (bool b)
{
value = b;
}

bool evaluate ()
{
return value;
}
string type ()
{
return "variable";
}
};
class negation : public formula
{
shared_ptr <formula> arg;
public: 
negation (formula f)
{
arg = f.address ();
}
bool evaluate ()
{
return !(arg -> evaluate ());
}
string type ()
{
return "negation";
}
};
class connected : public formula
{
shared_ptr <formula> lhs, rhs;
int C;
public:
connected (formula f, formula g, int c)
{
lhs = f.address ();
rhs = g.address ();
C = c;
}
bool evaluate ()
{
if (C == 0)
return lhs -> evaluate () && rhs -> evaluate ();
else if (C == 1)
return lhs -> evaluate () || rhs -> evaluate ();
else
return !(lhs -> evaluate ()) || rhs -> evaluate ();
}
string type ()
{
return "connected";
}
};
formula formula::operator&& (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 0));
formula f (temp);
return f;
}
formula formula::operator|| (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 1));
formula f (temp);
return f;
}
formula formula::operator>> (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 2));
formula f (temp);
return f;
}
formula formula::operator! ()
{
shared_ptr <formula> temp (new negation (*this));
formula f (temp);
return f;
}
int main ()
{
formula A (new variable), B (new variable);
A.assign(true);
B.assign(false);
formula x = A&&B, y = A||B, z = A>>B, w = !B;
cout << boolalpha;
cout << x.evaluate () << endl;
cout << y.evaluate () << endl;
cout << z.evaluate () << endl;
cout << w.evaluate () << endl << endl;
B.assign(true);
cout << boolalpha;
cout << x.evaluate () << endl;
cout << y.evaluate () << endl;
cout << z.evaluate () << endl;
cout << w.evaluate () << endl;
}

定义&&接受formulashared_ptr<formula>类型的参数。这是一种奇怪的不对称,会让你困惑不已。然后你试着把它应用到两个shared_ptr<formula>上。这是行不通的。

作为权宜之计,更改

cerr << (A&&B) -> type () << endl;

cerr << (*A && B) -> type () << endl;

然而从长远来看,这是不可持续的。

我建议将formula拆分为两个类,formulaformula_impl,其中formula_impl包含前formula的所有虚函数,formula包含shared_ptr<formula_impl>formula实现了它所能实现的(operator&&以及将来可能会实现的其他东西,如operator!operator||等等),并将evaluate等委托给共享指针指向的formula_impl。最终用户只能看到formula,看不到formula_impl

formula还应该定义静态函数,返回一个变量、一个否定和一个连接。

附加说明

对于虚函数来说,assign不是一个很好的选择。你只能赋值一个变量。这对其他类型的公式没有意义。我将完全去掉这个函数,并将值传递给variable的构造函数。

基类实现不应该打印"错误"或做任何其他事情。它们应该是纯虚函数

幻数(0是合取,1是析取)不是一个好主意。定义一个enum。将default的情况视为错误。

最新更新