CPP 設計模式學習

源地址 https://www.ev0l.art/index.php/archives/20/

備忘錄模式

  • 在一個類內部記錄另外一個類的快照狀態的模式。能夠再合適的時候跳回複用
  • 設計備忘錄的三大步驟:
  1. 設計記錄的節點,存儲記錄
    2.設計記錄的存儲: vector list map set 可使 鏈表 圖 數組 樹

3.操做記錄的類,記錄節點狀態,設置節點狀態,顯示節點狀態php

策略模式

  • 策略模式針對一組算法,將每個算法封裝到具備共同接口的獨立類中。
  • 從而使得他們能夠相互轉換,策略模式能夠在不影響客戶端的狀況下使算法發生改變。策略模式把行爲和環境分離開來,環境類負責維持和查詢行爲類。
  • 策略模式依賴多態,策略模式的抽象類,接口,抽象類的指針能夠訪問全部子類對象(純虛函數)
  • 各類策略的實現類。都必須集成抽象類。
  • 策略的設置接口類。設置不一樣的策略

設計模式 抽象工廠模式

  • 工廠模式: 客戶類和工廠類分開。
  • 消費者須要任何產品,只須要和工廠請求就能夠了。
  • 消費者無需修改就能夠接納新產品,缺點是當產品修改時,工廠類也要作相應的修改

=======ios

設計模式

簡單工廠模式

  • 基類存放數據 派生類存放操做
  • 再實現一個調用各個操做的靜態類,調用時返回派生類指針

代碼:算法

#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數據結構與算法

總覽

sjjg.jpg

概論

gl.png

算法的特性

sf.jpg

算法的衡量標準

sfbz.jpg

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; }
相關文章
相關標籤/搜索