c++虚函数实现计算表达式

c++虚函数实现计算表达式

简单的运算直接用运算符计算当然是简单的

但是如果在一个表达式中,每一步的运算都很复杂呢?

并且还需要随时添加复杂的表达式呢?

直接用运算符来构造就显得有些冗杂了吧,也很不方便修改。

于是我们可以构造虚函数来解决这样的问题

为了方便表达,我们这里举一个这样的例子:

( ( 1 + 2 ) × 3 + 4 ) ÷ 6 \left( \left( 1+2\right) \times 3+4\right) \div 6 ((1+2)×3+4)÷6

虽然比较简单,但是能体现大致的思想。

我们把它写成树,每个root都是一个运算方法。

如图所示:

树形图

每一个节点的运算参数要么是常数(此处我们叫做 TerminalExpression),要么是表达式(可能是 AddExpression 也有可能是 Mutiplyexpression)。

由此我们想到可以用一个统一的函数去返回他们的值:

getvalue()

也就是说每一个的节点(运算)都可以当作一个派生类,而他们的 getvalue() 函数由该派生类中定义的两个基类指针决定(由于基类指针可以指向派生类的对象!),派生类的对象类型由我们自己去输入。

说到这里可能有些云里雾里,下面我们给出代码会更直观一些:

#include<iostream>
#include<algorithm>

using namespace std;


class expression
{
public:
    float value;
    expression()
    {
        value = 0;
    }
    virtual float getvalue() = 0;
};

//所有的派生类(表达式)都有一个返回float型的getvalue()返回该基类派生类的value
class TerminalExpression: public expression
{
public:
    virtual float getvalue()
    {
        return value;
    }
};

class AddExpression: public expression
{
public:
    expression* l;                                  //基类的指针可以new派生类的对象!!!
    expression* r;
    virtual float getvalue()
    {
        value = l->getvalue() + r->getvalue();
        return value;
    }
};

class MultiplyExpression: public expression
{
public:
    expression* l;
    expression* r;
    virtual float getvalue()
    {
        value = l->getvalue() * r->getvalue();
        return value;
    }
};

class DivisionExpression: public expression
{
public:
    expression* l;
    expression* r;
    virtual float getvalue()
    {
        value = l->getvalue() / r->getvalue();
        return value;
    }
};

//((1 + 2)*3 + 4)/6 = 2.16667
int main()
{
    AddExpression *p = new AddExpression;
    p->l = new TerminalExpression;
    p->l->value = 1;
    p->r = new TerminalExpression;
    p->r->value = 2;                                    //左右两侧均为terminal赋值

    MultiplyExpression *q = new MultiplyExpression;
    q->l = new AddExpression;
    q->l = p;                                           //左侧的值为表达式p
    q->r = new TerminalExpression;
    q->r->value = 3;

    AddExpression *n = new AddExpression;
    n->l = new MultiplyExpression;
    n->l = q;                                           //左侧的值为表达式q
    n->r = new TerminalExpression;
    n->r->value = 4;

    DivisionExpression *d = new DivisionExpression;
    d->l = new AddExpression;
    d->l = n;                                           //左侧的值表达式为n
    d->r = new TerminalExpression;
    d->r->value = 6;

    cout<<d->getvalue()<<endl;
    return 0;
}

在代码中可以直观地看到,每一个运算是一个派生类,在main函数中是对其运算参数的赋值。

因此在main函数中,我们只需对每个运算的左参数和右参数进行赋值即可。

因此通过虚函数,我们可以轻易地增加运算,添加一个派生类即可,体现了C++对增添开放对修改封闭的特点。

其中最妙的地方在于基类指针可以new出派生类的对象,才能使该方法实现。

希望能和大家多多交流!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页