源地址 https://www.ev0l.art/index.php/archives/20/
備忘錄模式
- 在一個類內部記錄另一個類的快照狀態的模式,可以再合適的時候跳回復用
- 設計備忘錄的三大步驟:
- 設計記錄的節點,存盤記錄
2.設計記錄的存盤: vector list map set 可以使 鏈表 圖 陣列 樹
3.操作記錄的類,記錄節點狀態,設定節點狀態,顯示節點狀態
策略模式
- 策略模式針對一組演算法,將每一個演算法封裝到具有共同介面的獨立類中,
- 從而使得他們可以相互轉換,策略模式可以在不影響客戶端的情況下使演算法發生改變,策略模式把行為和環境分離開來,環境類負責維持和查詢行為類,
- 策略模式依賴多型,策略模式的抽象類,介面,抽象類的指標可以訪問所有子類物件(純虛函式)
- 各種策略的實作類,都必須集成抽象類,
策略的設定介面類,設定不同的策略
設計模式 抽象工廠模式
- 工廠模式: 客戶類和工廠類分開,
- 消費者需要任何產品,只需要和工廠請求就可以了,
- 消費者無需修改就可以接納新產品,缺點是當產品修改時,工廠類也要做相應的修改
=======
設計模式
簡單工廠模式
- 基類存放資料 派生類存放操作
- 再實作一個呼叫各個操作的靜態類,呼叫時回傳派生類指標
代碼:
#include <iostream>#include <string>using namespace std;class OP{public: double a; double b; virtual double jisuan() { return 0; }};class add : public OP{ double jisuan() { return a + b; }};class sub : public OP{ double jisuan() { return a - b; }};class divv : public OP{ double jisuan() { return a / b; }};class mul : public OP{ double jisuan() { return a * b; }};class Fac{public: static OP *selectop(char c) { switch (c) { case '+': return new add(); break; case '-': return new sub(); break; case '*': return new mul(); break; case '/': return new divv(); break; default: printf("you entered wrong caculation!!"); break; } }};int main(void){ OP *opr = Fac::selectop('/'); opr->a = 100; opr->b = 5; cout << opr->jisuan() << endl; return 0;}
方法工廠模式
- 把操作和實體化工廠的類分別抽象出來
- 通過繼承抽象類實作不同的操作
- 方法工廠模式就是簡單工廠模式把工廠進行抽象并且進行封裝后得到的
代碼:
#include <iostream>#include <string>using namespace std;class OP{public: double a, b; virtual double jisuan() { return 0; }};class add : public OP{ double jisuan() { return a + b; }};class sub : public OP{ double jisuan() { return a - b; }};class divv : public OP{ double jisuan() { return a / b; }};class mul : public OP{ double jisuan() { return a * b; }};class IFac{private: /* data */public: virtual OP *selectop() = 0;};class addop : public IFac{public: static OP *selectop() { return new add(); }};class subop : public IFac{public: static OP *selectop() { return new sub(); }};class divop : public IFac{public: static OP *selectop() { return new divv(); }};class mulop : public IFac{public: static OP *selectop() { return new mul(); }};int main(void){ IFac *opp = mulop::selectop(); opp->a=90; opp->b=100; cout << opp->jisuan()<<endl; return 0;}
抽象工廠模式
- 工廠模式: 客戶類和工廠類分開,
- 消費者需要任何產品,只需要和工廠請求就可以了,
- 消費者無需修改就可以接納新產品,缺點是當產品修改時,工廠類也要做相應的修改
- 消費者 工廠 商品都有自己的抽象類并且通過繼承 實體化 抽象介面 ,提供不同的服務
單例模式
- 單例模式確認某個類只有只有一個實體
- 有兩種實作模式: 1.匿名類的宣告 2.通過內部的靜態類指標來實作
- 單例模式:單例模式確保某一個類只有一個實體,
- 而且自行實體化并向整個系統提供這個實體單例模式
- 單例模式只應在有真正的“單一實體”的需求時才可使用,
public: int a=100; }aa;#include <iostream>#include <string>class{public: int a = 100;} aa;class SingleInstance{private: /* data */ int i = 0;public: static SingleInstance *instance; SingleInstance(int a) { this->i = a; } static SingleInstance *get_instance() { return instance; }};SingleInstance *SingleInstance::instance = new SingleInstance(1995);class B:public SingleInstance{};int main(void){ SingleInstance *s1=SingleInstance::get_instance(); SingleInstance *s2=B::get_instance(); std::cout<<(s1==s2)<<std::endl; std::cin.get(); return 0;}
代理模式
- 代理模式:代理模式給某一個物件提供一個代理物件,
- 并由代理物件控制對源物件的參考,
- 代理就是一個人或一個機構代表另一個人或者一個機構采取行動,
- 某些情況下,客戶不想或者不能夠直接參考一個物件,
- 代理物件可以在客戶和目標物件直接起到中介的作用,
- 客戶端分辨不出代理主題物件與真實主題物件,
- 代理模式可以并不知道真正的被代理物件,
- 而僅僅持有一個被代理物件的介面,這時候代理物件不能夠創建被代理物件,
- 被代理物件必須有系統的其他角色代為創建并傳入,
#include <iostream>#include <string>using namespace std;class girl{public: girl(string); girl(); ~ girl(); string name;private:}; girl:: girl(string s1){ name = s1;} girl::~ girl(){} girl::girl() { name = "不知名的!"; } class gift { public: virtual void gift1() = 0; virtual void gift2() = 0; }; class gg:public gift { public: gg(girl); ~gg(); void gift1() { cout << mm.name << "送你禮物1" << endl; } void gift2() { cout << mm.name << "送你禮物2" << endl; } private: girl mm; }; gg::gg(girl m) { mm = m; } gg::~gg() { } class proxy :public gift { private : gg gg1; public: proxy(girl mm) :gg1(mm) { } void gift1() { gg1.gift1(); } void gift2() { gg1.gift2(); } };int main(void){ girl mm1("小妹妹"); proxy p1(mm1); p1.gift1(); p1.gift2(); cin.get(); return 0;}
迭代器模式
- 迭代子模式:迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內部表象,
- 多個物件聚在一起形成的總體稱之為聚集,聚集物件是能夠包容一組物件的容器物件,
命令列模式
- 把執行命令單獨建一個類,專職做命令的執行作業
- 命令的執行者專么建一個基類,存放執行不同命令的類繼承自這個基類,通過執行不同命令劃分,
- 再建一個類統籌這些執行命令的類,呼叫執行命令的類,
- 代碼:
- 命令模式示例代碼
#include <iostream>#include <string>#include <list>using namespace std;class doing{public: void action1() { cout << "lalala 吃飯了" << endl; } void action2() { cout << "是時候運動了!!!!!" << endl; }private:};class Command{public: Command(doing * d) { reciver = d; } virtual void do_doing() = 0; protected: doing* reciver; };class action1_command:public Command{public: action1_command(doing* d) :Command(d) { } void do_doing() { reciver->action1(); }};class action2_command :public Command{public: action2_command(doing* d) :Command(d) { } void do_doing() { reciver->action2(); }};class waiter{public: void set_action(Command* c) { this->command = c; } void do_action() { this->command->do_doing(); }protected: Command* command;};class waiter_n {public: void set_action(Command* c) { this->command.push_back(c); } void do_action() { auto n = command.begin(); while (n!=command.end()) { (*n)->do_doing(); n++; } }private: list<Command*> command;};int main(void){ doing* dd = new doing(); Command* action_command1 = new action1_command(dd); Command* action_command2 = new action2_command(dd); waiter* w = new waiter(); w->set_action(action_command1); w->do_action(); w->set_action(action_command2); w->do_action(); cout << endl; waiter_n* ww = new waiter_n(); ww->set_action(action_command1); ww->set_action(action_command2); ww->do_action(); return 0;}
責任鏈模式:
- 一級傳達另一級,知道沒有上級,直到最高級
- 責任鏈模式示例
#include <iostream>#include <string>using namespace std;class Request{public: string request_name; string request_type; int n;private: };class Manager {public: Manager(string n, string j, int id) { name = n; job = j; classid = id; } void setSuper(Manager *p) { this->super = p; } virtual void apply(Request*) = 0; int classid; Manager* super; string name; string job;private: };class zhuguan:public Manager{public: zhuguan(string n, int id) :Manager(n,"主管", id) {} void apply(Request* r) { if (r->n > this->classid) { cout << r->request_type << "\t" << r->request_name << "\t 被" << this->job << this->name << "審閱!無權限,將繼續向上遞交!!" << "classid=" << this->classid << endl; super->apply(r); } else { cout << r->request_type << "\t" << r->request_name << "\t 被"<<this->job<<this->name<<"批準!!!"<<"classid="<<this->classid<< endl; } }private:};class zongjian :public Manager{public: zongjian(string n, int id) :Manager(n, "總監", id) {} void apply(Request* r) { if (r->n > this->classid) { cout << r->request_type << "\t" << r->request_name << "\t 被" << this->job << this->name << "審閱!無權限,將繼續向上遞交!!" << "classid=" << this->classid << endl; super->apply(r); } else { cout << r->request_type << "\t" << r->request_name << "\t 被" << this->job << this->name << "批準!!!" << "classid=" << this->classid << endl; } }private:};class zongjingli :public Manager{public: zongjingli(string n) :Manager(n, "總經理", 1000) {} void apply(Request* r) { cout << r->request_type << "\t" << r->request_name << "\t 被" << this->job << this->name << "批準!!!" << "classid=" << this->classid << endl; }private:};int main(void){ Request* request = new Request(); request->request_name = "生病請10天假"; request->request_type = "病假"; request->n = 50; zhuguan* zg = new zhuguan("小芳", 10); zongjian* zj = new zongjian("小明", 30); zongjingli* zjl = new zongjingli("老大"); zg->setSuper(zj); zj->setSuper(zjl); zg->apply(request); return 0;}
20140903資料結構與演算法
總覽

概論

演算法的特性

演算法的衡量標準

Boost和演算法
boost Array 第一只boost 程式
- 使用boost 必須下載安裝適當的編譯好的包,
- 各個VS 使用的版本不一樣
- Linux只能自己編譯
- boost 的命名空間為boost
- boost第一個程式(array)
#include <iostream>#include <boost/array.hpp>#include <string>using namespace std;int main(void){ boost::array<int,10> arr = { 0,1,2,3,4,5,6,7,8,9 }; boost::array<int, 10>::iterator ib = arr.begin(); boost::array<int, 10>::iterator ie = arr.end(); for (;ib!=ie;ib++) { cout << *ib << endl; } cin.get(); return 0;}
boost 庫的學習 boost_array_bind_fun_ref
std 方式
- 系結已有函式增加新的引數但是不改變原來的函式(std 方式)
使用:
- 1執行操作的類繼承自 std::binary_function<>
- 2.使用bind1st()
代碼:
- bind1st示例代碼(bind1st.cpp)
#include <iostream>#include <string>#include <functional>#include <list>#include <algorithm>#include "boost/bind.hpp"using namespace std;using namespace boost;class jia:public binary_function<int,int,void>{public:void operator ()( int i, int j) const{ cout << i+j << endl;}private:};int main(void){ list <int> ls1; ls1.push_back(5); ls1.push_back(15); ls1.push_back(125); for_each(ls1.begin(), ls1.end(), bind1st(jia(),10)); cin.get(); return 0;}
boost方式
- boost::bind示例代碼
#include <iostream>#include <string>#include <functional>#include <list>#include <algorithm>#include "boost/bind.hpp"using namespace std;using namespace boost;class jia:public binary_function<int,int,void>{public:void operator ()( int i, int j) const{ cout << i+j << endl;}private:};void add(int i, int j){ cout << i + j << endl;}int main(void){ list <int> ls1; ls1.push_back(5); ls1.push_back(15); ls1.push_back(125); //std 方式 for_each(ls1.begin(), ls1.end(), bind1st(jia(),10)); //boost 方式 for_each(ls1.begin(), ls1.end(), bind(add,13, _1)); cin.get(); return 0;}
- boost詳解
這個從新做一個文章吧,在這里放不下,,,
boost::function 庫
- boost::function 庫提供了一個類模板 boost::function,它是一個仿函式類,用于封裝各種函式指標通常用來和bind結合起來使用,當仿函式沒有系結任何指標時,會拋出 boost::bad_function_call例外,
boost::ref
- 不能拷貝物件用boost::ref()
RAII
- 避免記憶體泄漏,把堆上的記憶體當做堆疊使用
智能指標 smartpointers 庫
類的虛函式表
- 類有一個虛函式表,存盤著所有虛函式的地址,
- 類總是把虛函式表放在最前面
- 一種訪問類的虛函式的方法(代碼如下:)
- 不管基類中是公有,私有,都不影響子類集成虛函式
- 虛函式順序:基類-》子類
- 多重繼承子類會有多個虛函式表,每個虛函式表繼承自每個基類的虛函式表
#include <iostream>using namespace std;class A{public: void virtual a() { std::cout << "A --> a" << endl; } void virtual b() { std::cout << "A--> b" << endl; } void virtual c() { std::cout << "A--> c" << endl; }private:};class B :public A{public: void virtual a() { std::cout << "B--> a" << endl; } void virtual b() { std::cout << "B--> b" << endl; }};typedef void (*Pfunc) (void);int main(void){ B b; cout << "B is " <<sizeof(b) << endl; Pfunc pfc; for (int i = 0; i < 3; i++) { /* (&b) 取出B的地址 (int *)(&b) 轉換b的地址為int 型別,方便后期訪問緊跟著它的記憶體 *(int *)(&b) 取出B里面的內容(虛函式表的地址) (int *) *(int *)(&b) 把虛函式表的地址轉換為int型別,方便后期訪問緊跟著它的記憶體 (int *) *(int *)(&b) + i 利用地址存盤的機制,+1 自動跳過4(8)個位元組,訪問下一個記憶體內容,訪問存盤在虛函式表里面的函式地址 (Pfunc)* 將虛函式表李的函式指標地址轉換為 pFunc 型別的函式指標地址,方便呼叫 pfc(); 呼叫 */ pfc = (Pfunc)*((int *) *(int *)(&b) + i); pfc(); } cin.get(); return 0;}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/75514.html
標籤:C++
上一篇:C++ 一篇搞懂繼承的常見特性
