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

2014-11-24 12:36:28 · 作者: · 浏览: 2

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

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

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

完整代码如下:

#include

#include

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 eva l() 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 eva l() const

{

return p->eva l();

}

};

class Int_node: public Expr_node

{

private:

int n;

public:

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

void print(ostream &o) const

{

o << n;

}

int eva l() 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 eva l() const

{

if(op == "-")

return -opnd.eva l();

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 eva l() const

{

int op1 = left.eva l();

int op2 = right.eva l();

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 eva l() const

{

if(left.eva l())

return middle.eva l();

else

return right.eva l();

}

};

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()

{

Expr t = Expr("*",

Expr("-", Expr(5)),

Expr("+", Expr(3), Expr(4)));

cout << t << "=" << t.eva l() << endl;

Expr t2 = Expr("-", Expr(5), Expr(" :", Expr(0), Expr(1), Expr(2)));

cout << t2 << "=" << t2.eva l() << endl;

}

运行结果如下:

((-5)*(3+4))=-3

(5-(0 1