国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

[Boolan] C++第三周 類的關系。 復合,委托,繼承

2019-11-10 17:14:03
字體:
來源:轉載
供稿:網友

1. Composition復合

has a的關系,表示一個類是另一個類的成員變量,一個類包含另一個類class A;class B {public: B(){} ~B(){}PRivate: A a; int b;};

這里寫圖片描述

構造與析構

構造-由內而外:B的構造函數會首先調用A的默認構造函數(編譯器自己調用,如果需要傳遞參數,需要在初始化列表顯示調用),然后在調用自己的構造函數 B::B(...):A(){...}析構-由外而內:B的析構函數首先執行自己的,然后才調用A的析構函數 B::~B(...){... ~A()}

Adapter作用

新需求所要求的所有功能在一個已有的C類中已經全部實現,但是C中功能繁多,此時可以設計一個類D對C的功能進行一次封裝,僅暴露需要的結構結構,此時就非常適合Composition關系class C;class D{public: void func() { c.func(); }private: C c;};

2. Delegation委托

has a point類的成員變量是另一個類的指針,class A;class B {public: B(){} ~B(){}private: A *a; int b;};

這里寫圖片描述

這種方法有個名詞pImpl(Pointer to IMPLementation),簡單理解就是接口與實現分離

參考鏈接: 1. 明智地使用Pimpl 2. 編譯防火墻——C++的Pimpl慣用法解析

典型用例

C++11中的string就是用了這種方法,方法和實際實現分離,這樣就可以在兩個字符串相同的時候,就使用同一塊內存,當其中一個發生改變時就重新分配一塊內存可以通過下列代碼進行驗證,但請確保是在C++11版本(因為我只測試了這個版本)#include <stdio.h>#include <string>using std::string;int main(int argc, char *argv[]){ string s1("123456789"); string s2(s1); string s3("123456789"); printf("s1=%p, s2=%p, s3=%p/n", s1.c_str() , s2.c_str(), s3.c_str()); s1 += "00"; printf("s1=%p, s2=%p, s3=%p/n", s1.c_str() , s2.c_str(), s3.c_str()); return 0;}----------------------s1=00FC2AAC, s2=00FC2AAC, s3=00FC2ACCs1=00FC3AF4, s2=00FC2AAC, s3=00FC2ACC

3. Inheritance繼承

繼承 is a,C++分為三種方式public,protected, private.使用最廣泛的是publicclass A{public: A(){} virtual ~A(){}}class B : public A{};

這里寫圖片描述

構造與析構

構造-由內而外:B的構造函數首先調用A的默認構造函數,然后在執行自己 B::B():A(){...};析構-由外而內:B的析構函數首先執行自己,然后才調用A的析構函數 B::~B(...){...~A()};注意:基類的析構函數必須是virual的,否則會出現undefined behavior

4. 應用

觀察者模式

委托+復合類圖 這里寫圖片描述代碼#include <stdio.h>#include <string>#include <vector>#include <iostream>using std::string;using std::vector;using namespace std;class Subject;class Observer{public: virtual void update(Subject *sub, int value) = 0;};class Subject{public: void attach(Observer*obs) { m_views.push_back(obs); } void set_val(int value) { m_value = value; notify(); } void notify() { for(int i = 0; i < m_views.size(); i++){ m_views[i]->update(this, m_value); } }private: int m_value; vector<Observer*> m_views;};class View : public Observer{public: void update(Subject *sub, int value) { m_watchValue = value; } void paintView() { cout << m_watchValue<< endl; }private: int m_watchValue;};int main(int argc, char *argv[]){ View v1; View v2; Subject s; s.attach(&v1); s.attach(&v2); s.set_val(100); v1.paintView(); v2.paintView(); cout << "-----------------------" << endl; s.set_val(200); v1.paintView(); v2.paintView(); return 0;}///////////////////////////----------------------100100-----------------------200200

組合模式Composite(結構型)

參考鏈接: 設計模式(七)組合模式Composite(結構型)組合模式(Composite Pattern )C++設計模式-Composite組合模式典型應用場景 windows的文件夾與文件系統,文件夾中又有文件類圖 這里寫圖片描述代碼class Component{public: Component(int val):m_value(val){} virtual void add(Component*){}private: int m_value;};class Primitive:public Component{public: Primitive(int val):Component(val){}};class Composite:public Component{public: Composite(int val):Component(val){} void add(Component *elem) { c.push_back(elem); }private: vector<Component*> c;};

原型模式prototype

參考鏈接 c++原型模式(Prototype)原型模式(Prototype)C++實現應用場景 原型模式是通過已經存在的對象的接口快速方便的創建新的對象。類圖 這里寫圖片描述代碼#include <iostream>using namespace std;enum imageType{ LSAT, SPOT};class Image{public: virtual void draw() = 0; static Image* findAndClone(imageType); virtual ~Image() {}protected: virtual imageType returnType() = 0; virtual Image *clone() = 0; static void addPrototype(Image *image) { _prototypes[_nextSlot++] = image; }private: static Image* _prototypes[10]; static int _nextSlot;};Image *Image::_prototypes[];int Image::_nextSlot;Image *Image::findAndClone(imageType type){ for(int i = 0 ; i < _nextSlot; i++) { if(_prototypes[i]->returnType() == type) { return _prototypes[i]->clone(); } } return NULL;}//////////////////////////////////////////////////////////////////////////class LandSatImage:public Image{public: imageType returnType() { return LSAT; } void draw() { cout << "LandSatImage::draw " << _id <<endl; } Image *clone() { return new LandSatImage(1); }protected: LandSatImage(int dummy) { _id = _count++; }private: static LandSatImage _landSatImage; LandSatImage(){ addPrototype(this); } int _id; static int _count;};LandSatImage LandSatImage::_landSatImage;int LandSatImage::_count = 1;//////////////////////////////////////////////////////////////////////////class SpotImage:public Image{public: imageType returnType() { return SPOT; } void draw() { cout << "SpotImage::draw "<< _id <<endl; } Image *clone() { return new SpotImage(1); }protected: SpotImage(int dummy) { _id = _count++; }private: SpotImage() { addPrototype(this); } static SpotImage _spotImage; int _id; static int _count;};SpotImage SpotImage::_spotImage;int SpotImage::_count = 1;//////mainconst int Num_IMAGES = 8;imageType input[Num_IMAGES] = { LSAT, LSAT, LSAT, LSAT, SPOT, SPOT, LSAT};int main(){ Image *images[Num_IMAGES]; int i = 0; for(i = 0; i < Num_IMAGES; i++) { images[i] = Image::findAndClone(input[i]); } for(i = 0; i < Num_IMAGES; i++) { images[i]->draw(); } for(i = 0; i < Num_IMAGES; i++) { delete images[i]; } return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 大英县| 梁河县| 汾阳市| 定陶县| 循化| 铁力市| 石台县| 拉萨市| 黔西| 湟源县| 仁布县| 黑水县| 临潭县| 镇雄县| 饶平县| 辽中县| 清徐县| 扶风县| 青冈县| 乡宁县| 崇信县| 广东省| 萝北县| 泸溪县| 河间市| 遂昌县| 陆川县| 三门峡市| 通道| 碌曲县| 丹江口市| 广安市| 余庆县| 和静县| 桂阳县| 共和县| 武定县| 合川市| 东方市| 苍溪县| 那曲县|