当前位置:编程学习 > C/C++ >>

C++沉思录读书笔记(8章)-一个面向对象程序范例2

 

此回是针对上回所设计方案的扩展,下面将会演示

(1)如何增加计算表达式的值的功能

(2)如何增加新的节点类型(已经有表示单个数、一元操作符、二元操作符的节点类型Int_node\Unary_node\Binary_node,将演示如何增加三元操作符(Ternary_node))

 

完整代码如下:

 

#include <iostream> 

#include <string> 

using namespace std; 

 

class Expr_node 

    friend class Expr;  //友元类可以被继承 

    int use;                  //引用计数 

public: 

    virtual void print(ostream&) const = 0; 

public: 

    Expr_node():use(1) {} 

    virtual ~Expr_node() {} 

    virtual int eval() const = 0; 

}; 

 

class Expr                     //句柄类 

    friend ostream& operator<<(ostream &o, const Expr &e); 

private: 

    Expr_node *p;       //指向基类的指针 

public: 

    Expr(int n); 

    Expr(const string &op, Expr t); 

    Expr(const string &op, Expr left, Expr right); 

    Expr(const string &op, Expr left, Expr middle, Expr right); 

    Expr(const Expr &t); 

    Expr& operator=(const Expr&); 

    ~Expr() 

    {  

        if(--p->use == 0) 

            delete p; 

    } 

    int eval() const 

    { 

        return p->eval(); 

    } 

}; 

 

class Int_node: public Expr_node 

private: 

    int n; 

public: 

    Int_node(int k):n(k) {} 

    void print(ostream &o) const 

    { 

        o << n; 

    } 

    int eval() const { return n; } 

};  

 

 

class Unary_node: public Expr_node 

private: 

    //friend class Expr; 

    string op; 

    Expr opnd; 

public: 

    Unary_node(const string &a, Expr b):op(a), opnd(b) {} 

    void print(ostream &o) const 

    { 

        o << "(" << op << opnd << ")"; 

    } 

    int eval() const 

    { 

        if(op == "-") 

            return -opnd.eval(); 

        throw "error!错误的一元操作符"; 

    } 

}; 

 

class Binary_node: public Expr_node 

private: 

    //friend class Expr; 

    string op; 

    Expr left; 

    Expr right; 

public: 

    Binary_node(const string &a, Expr b, Expr c):op(a), left(b), right(c) {} 

    void print(ostream &o) const 

    { 

        o << "(" << left << op << right << ")"; 

    } 

    int eval() const 

    { 

        int op1 = left.eval(); 

        int op2 = right.eval(); 

        if(op == "-") return op1 - op2; 

        if(op == "+") return op1 + op2; 

        if(op == "*") return op1 * op2; 

        if(op == "/") return op1 / op2; 

        throw "error! 错误的二元操作符!"; 

    } 

}; 

 

class Ternary_node: public Expr_node 

private: 

    string op; 

    Expr left; 

    Expr middle; 

    Expr right; 

public: 

    Ternary_node(const string& a, Expr b, Expr c, Expr d):op(a), left(b), middle(c), right(d) {} 

    void print(ostream &o) const 

    { 

        o << "(" << left << "?" << middle << ":" << right << ")"; 

    } 

    int eval() const 

    { 

        if(left.eval()) 

            return middle.eval(); 

        else 

            return right.eval(); 

    } 

}; 

 

Expr::Expr(int n) { p = new Int_node(n); } 

Expr::Expr(const string& op, Expr t) { p = new Unary_node(op, t); } 

Expr::Expr(const string &op, Expr left, Expr right) { p = new Binary_node(op, left, right); } 

Expr::Expr(const string &op, Expr left, Expr middle, Expr right) { p = new Ternary_node(op, left, middle, right); } 

Expr::Expr(const Expr& t) { p = t.p; ++p->use; } 

 

Expr& Expr::operator=(const Expr& rhs) 

    rhs.p->use++;  

    if(--p->use == 0) 

        delete p; 

    p = rhs.p; 

    return *this; 

 

ostream& operator<<(ostream &o, const Expr &e) 

    e.p->print(o); 

    return o; 

 

void main() 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,