组合模式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <list> #include <string> using namespace std; //component class IFile { public: virtual void displaye() = 0; virtual int add(IFile* iFile) = 0; virtual int remove(IFile *iFile) = 0; virtual list<IFile*>* getChild() = 0; }; //Leaf class File :public IFile { public: File(string name):m_name(name){} virtual void displaye() { cout << m_name << endl; } virtual int add(IFile* ifile) { return -1; } virtual int remove(IFile* ifile) { return -1; } virtual list<IFile*>* getChild() { return NULL; } private: string m_name; }; //目录:Composite class Dir :public IFile { public: Dir(string name) :m_name(name) { m_list = new list<IFile*>; } virtual void displaye() { cout << m_name << endl; } virtual int add(IFile* ifile) { m_list->push_back(ifile); return 0; } virtual int remove(IFile* ifile) { m_list->remove(ifile); return 0; } virtual list<IFile*> * getChild() { return m_list; } private: string m_name; list<IFile*> *m_list; }; void showTree(IFile* root, int level) { if (root == NULL) return; int i = 0; for (i = 0;i < level;i++) { printf("\t"); } root->displaye(); list<IFile*> *list1 = root->getChild(); if (list1 != NULL) { for (list<IFile*>::iterator iter = list1->begin();iter != list1->end();iter++) { if ((*iter)->getChild() == NULL) { //这是文件 for (i = 0;i < level;i++) { printf("\t"); } (*iter)->displaye(); } else { showTree(*iter, level + 1); } } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ExpressNode.h ======================================== #pragma once #include <iostream> using namespace std; class ExpressNode { public: friend class Express; int getUse(void) const; void setUse(int); friend ostream& operator<<(ostream &os, const ExpressNode& ExprNode) { //s输出表达式自身 ExprNode.print(os); return os; } ExpressNode(void) :use(1){} ~ExpressNode(); protected: virtual void print(ostream& os) const = 0; virtual int eval() const = 0; private: int use; }; ======================================= ExpressNode.cpp #include "ExpressNode.h" ExpressNode::~ExpressNode(){} int ExpressNode::getUse()const { return use; } void ExpressNode::setUse(int use1) { use = use1; } &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Express.h ========================================= #pragma once #include "ExpressNode.h" #include <iostream> using namespace std; class Express { public: Express(int);//ValueNode Express(char, const Express);//UnaryNodoe(char,int) Express('+',t,12) Express(char, const Express, const Express);//BinaryNode(char,int,int),("+",3,4) Express(const Express&); Express& operator=(const Express&); friend ostream& operator<<(ostream& os, const Express& e) { os << *(e.p); return os; } ~Express(void); int eval()const; private: class ExpressNode* p;//具体的功能由这个类实现,这个类派生了各种各样的表达式 }; ======================================== Express.cpp #include "Express.h" #include "ValueNode.h" #include "UnaryNode.h" #include "BinarayNode.h" Express::Express(int a) { p = new ValueNode(a); } Express::Express(char c, const Express e) { p = new UnaryNode(c, e); } Express::Express(char c, const Express el, const Express er) { p = new BinaryNode(c, el, er); } Express::Express(const Express& el) { p = el.p; p->setUse(p->getUse() + 1); } Express& Express::operator=(const Express& el) { (el.p)->setUse((el.p)->getUse() + 1); p->setUse(p->getUse() - 1); if (p->getUse() == 0) delete p; p = el.p; return *this; } Express::~Express() { p->setUse(p->getUse() - 1); if (p->getUse() == 0) delete p; } int Express::eval() const { return p->eval(); } &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ValueNode.h #pragma once #include "Express.h" #include "ExpressNode.h" class ValueNode : public ExpressNode { public: friend class Express; ValueNode(void) {} ValueNode(int value):m_value(value){} ~ValueNode() { } private: void print(ostream& os) const { os << m_value; } int eval()const { return m_value; }; int m_value; }; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& BinarayNode.h ========================================= #pragma once #include "ExpressNode.h" #include "Express.h" class BinaryNode : public ExpressNode { public: friend class Express; //BinaryNode(void); BinaryNode(char, class Express, class Express); ~BinaryNode(); private: void print(ostream&) const; int eval() const; char opend; class Express left; class Express right; }; ========================================= BinarayNode.cpp #include "BinarayNode.h" BinaryNode::BinaryNode(char c, class Express left1, class Express right1):opend(c),left(left1),right(right1) { } BinaryNode::~BinaryNode() { } void BinaryNode::print(ostream& os) const { os << "(" << left << opend << right << ")"; } int BinaryNode::eval() const { int op1 = left.eval(); int op2 = right.eval(); if (opend == '+') return op1 + op2; if (opend == '-') return op1 - op2; if (opend == '*') return op1*op2; if (opend == '/' && op2 != 0) return op1 / op2; throw "error,二叉归并向上中的根操作符不正确"; } &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& UnaryNode.h #pragma once #include "Express.h" #include "ExpressNode.h" class UnaryNode :public ExpressNode { public: friend class Express; //UnaryNode(void); UnaryNode(char c, class Express left1); ~UnaryNode(); private: void print(ostream& os) const; int eval() const; char opend; class Express left; }; ======================================== UnaryNode.cpp #include "Express.h" #include "UnaryNode.h" UnaryNode::UnaryNode(char c, class Express left1) :opend(c), left(left1) { } UnaryNode::~UnaryNode(void) { } void UnaryNode::print(std::ostream &os)const { os << "(" << opend << left << ")"; } int UnaryNode::eval() const { if (opend == '-') return (-1)*left.eval(); throw "error, 有错误的操作符"; } &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& #include "ExpressNode.h" #include "ValueNode.h" #include "UnaryNode.h" #include "BinarayNode.h" #include "Express.h" int main(void) { Express t = Express(3); t = Express('+', t, 12); cout << t << "=" << t.eval() << endl; Express y = Express('-', 4); cout << y << "=" << y.eval() << endl; Express t1 = Express('*', Express('-', 5), Express('+', 3, 4)); cout << t1 << "=" << t1.eval() << endl; system("pause"); return 0; }