源地址 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; }