CPP 设计模式学习
源地址 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;
}
CPP 设计模式学习的更多相关文章
- C++ 与设计模式学习(其一)
记得曾经一年前,听到同学再说设计模式,当时觉得不怎么重要,所以就没有去系统的学习,这一放,就是一年,直到前段时间,面试了一个阿里巴巴的职位,要我谈谈对于设计模式的看法. 之后就好好了看了一些文章,好好 ...
- 设计模式学习系列6 原型模式(prototype)
原型模式(prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个新对象的时候根本无需知道任何创建细节,只需要请求圆形对象的copy函数皆可. 1 ...
- Java-马士兵设计模式学习笔记-总结
<马士兵设计模式学习>学习了以下模式: 1.装饰者模式(例子:水管工,木工) 2.策略模式(例子:老师用职称比大小.学生用成绩比大小) 3.简单工厂模式(例子:VechileFactory ...
- Java设计模式学习资源汇总
本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...
- python之路,Day24 常用设计模式学习
python之路,Day24 常用设计模式学习 本节内容 设计模式介绍 设计模式分类 设计模式6大原则 1.设计模式介绍 设计模式(Design Patterns) --可复用面向对象软件的基础 ...
- 设计模式学习--复合模式(Compound Pattern)
设计模式学习--复合模式(Compound Pattern) 概述 ——————————————————————————————————————————————————— 2013年8月4日<H ...
- 北京设计模式学习组bjdp.org第7次活动(2013.08.04)回顾会纪要
时间:2013.08.04,9am-7pm 地点:北京龙泉寺(北京凤凰岭风景区内) 参加人数:北京龙泉寺信息中心(20人).北京设计模式学习组(9人) 活动要点: 1)寺院巡礼:义工师兄带领参观寺院. ...
- 设计模式学习--Factory Method
What Factory Method:定义一个创建对象的接口,让子类来决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. Why Factory Method是一个比較基 ...
- Java设计模式学习总结
设计模式基础学习总结 这篇总结主要是基于我之前设计模式基础系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 更多详细内容可以查看我的专栏文章:设计模式 ...
随机推荐
- How to use AutoMapper
http://docs.automapper.org/en/stable/Getting-started.html IMappingExpression<TSource, TDestinatio ...
- ping的使用
ping -t cnblogs.com 可以一直ping网址显示对应的响应时间
- TP-admin即基于ThinkPHP5拿来即用高性能后台管理系统
TP-Admin即基于ThinkPHP5的web后台管理系统(总结一套自己的后台管理系统,方便自己后续的项目开发.) 主要特性:自适应手机端.支持国际化.吸取其他CMF框架优点.多站点部署.日志记录. ...
- jsp中文乱码六种情况---解决方案
转 jsp中文乱码六种情况---解决方案 2016年10月22日 21:32:55 阅读数:10672 来源:http://blog.csdn.net/lovesummerforever/articl ...
- ORACLE内部操作
当执行查询时,ORACLE采用了内部的操作. 下表显示了几种重要的内部操作. ORACLE Clause 内部操作 ORDER BY SORT ORDER BY UNION UNION-ALL MIN ...
- JS的作用域链与this指向
JS的作用域链是在函数创建时创建的.而this对象是在函数运行期间绑定的. 下面看几个例子,说明JS的作用域链和this是两套分离的链. 1) var name = 'window下的name< ...
- H3C MP-Group方式配置PPP MP
- springmvc 多文件/文件夹上传 下载
注入依赖 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding&g ...
- php 使用正则匹配中文 返回结果
$str = 'eg5455正则匹配中文123三国杀'; $patten='/[\x{4e00}-\x{9fa5}]+/u'; $a = preg_match($patten, $str, $mn); ...
- [转]UEditor编辑器两个版本任意文件上传漏洞分析
0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...