[Boolan] C++第三周 类的关系。 复合,委托,继承
来源:互联网 发布:厦门大数据协会 编辑:程序博客网 时间:2024/05/16 10:44
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.使用最广泛的是public
class 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;}
0 0
- [Boolan] C++第三周 类的关系。 复合,委托,继承
- C++类和类之间的关系(Boolan笔记第三周)
- c++面向对象之复合(composition)、委托(delegation)、继承(inheritance)--(boolan)
- 复合,继承,委托
- 类的两种关系——继承和复合
- Objective-C的继承与复合
- 【Objective-C编程】浅析Objective-C的继承与复合
- [Boolan] C++第三周学习笔记
- Boolan* C++课程第三周笔记
- Boolan C++设计模式 第三周笔记
- C++面向对象第三周笔记<Boolan>
- Boolan C++ 设计模式 第三周
- 03 C++中复合、委托和继承的基本用法(学自Boolean)
- Objective-C 类继承关系
- Objective-C 类的复合
- [Boolan] 这周的笔记
- C++-继承:基类与派生类的关系
- .NET(C#):判断Type类的继承关系
- 【BZOJ 3786】星系探索 splay维护dfs序
- POJ 1845 Sumdiv(因子和 大数模 费马小定理)
- PV、UV、IP之间的区别与联系
- .NET Core 最小化发布
- DVWA系列(二)----DVWA环境搭建
- [Boolan] C++第三周 类的关系。 复合,委托,继承
- BZOJ 1924 所驼门王的宝藏【思维建图+强连通缩点+DAG图上做最长路】这题好尼玛综合........
- centos7 安装MySQL数据库
- java零基础入门知识3.3——Swing基础知识总结(四)
- 使用Java对UTF8URL进行编码解码以及进行编码方式的判断
- 【studio导入项目遇到问题二】Error:Unable to calculate percentage: 6686 of -3459085. All inputs must be >= 0
- matlab2014a安装密钥
- Effective C++读书笔记
- SQL面试题-查询课程