一個面向對象程序範例

1.最近幾天在看c++ 沉思錄。裏面舉的例子確實讓我茅塞頓開,醍醐灌頂哈。node

2.我把代碼貼上去吧。根據原書的代碼敲的。ios

這一章的內容要解決的是如何表示一個表達式樹。c++

做者將全部類型的表達式都隔離開了,就用一個類來提供全部的接口,管理內存。讓用戶避免記住麻煩的用法和內存管理。this

至關巧妙spa

//Expr_node.h
#include <iostream>
using namespace std;

class Expr;
class Expr_node
{
	friend ostream& operator<<(ostream& o, const Expr& t);
	friend ostream& operator<<(ostream& o, const Expr_node& e)
	{
		e.print(o);
		return o;
	}

	friend class Expr;

	int use;
protected:
	Expr_node() : use(1) { }
	virtual void print(ostream& ) const = 0;
	virtual int eval() const = 0;
	virtual ~Expr_node() {}
};

class Expr
{
	friend ostream& operator<<(ostream&, const Expr&);
	friend class Expr_node;
	Expr_node* p;
public:
	Expr(int); // create a int_node;
	Expr(const string &, Expr);
	Expr(const string &, Expr, Expr);
	Expr(const string& , Expr, Expr, Expr);
	Expr(const Expr& t) { p = t.p; ++ p->use;};
	Expr& operator=(const Expr&);
	~Expr(){ if( -- p->use == 0) delete p;}

	int eval() const {return p->eval();}
};

class Int_node: public Expr_node 
{
	friend class Expr;
	int n;

	Int_node(int k):n(k) {}
	void print(ostream& o) const { o << n;}
	virtual int eval() const { return n;}
};
//unary node
class Unary_node : public Expr_node
{
	friend class Expr;
	string op;
	Expr opnd;
	Unary_node(const string& a, Expr b):op(a), opnd(b) {}
	void print(ostream& o) const
	{ o <<"( " << op << opnd << ") ";}
	int eval() const;
};

class Binary_node : public Expr_node {
	friend class Expr;
	string op;
	Expr left;
	Expr right;
	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;
};

class Ternary_node : public Expr_node
{
	friend class Expr;
	string op;
	Expr left;
	Expr middle;
	Expr right;

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

	void print(ostream& o) const;
	int eval( ) const;
};
//Expr_node.cpp
#include "Expr_node.h"

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::operator=(const Expr& rhs)
{
	rhs.p->use++;
	if (-- p->use == 0)
	{
		delete p;
	}
	p = rhs.p;
	return *this;
}

ostream& operator<<(ostream& o, const Expr& t)
{
	t.p->print(o);
	return o;
}

int Unary_node::eval() const 
{
	if (op == "-")
		return -opnd.eval();
	throw "error, bad op " + op + " int UnaryNode";
}

int Binary_node::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 == "/" && op2 != 0)  return op1 / op2;

	throw "error, bad op " + op + " in BinaryNode";
}

void Ternary_node::print(ostream& o) const
{
	o<<"( "<<left<<" ? "<<middle<<" :  "<<right<<") ";
}
int Ternary_node::eval() const
{
	if (left.eval())
		return middle.eval();
	else
		return right.eval();
}
//main.cpp
#include <iostream>

#include "Expr_node.h"

using namespace std;
int main(int argc, char const *argv[])
{
	Expr t = Expr("*", Expr("-", 5), Expr("+", 3,4));
	cout<<t<<" = "<< t.eval() <<endl;
	t = Expr("*", t, t);
	cout<<t<<" = "<< t.eval() <<endl;
	return 0;
}
相關文章
相關標籤/搜索