2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用
今天白天主要看了boost库的应用,主要是经常使用的一些库,array,bind,function,regex,thread,unordered,ref,smartpointers库,晚上看了看设计模式。主要就是外观模式。建造者模式和观察者模式。我们从boost简要说起。
事实上boost的库好多东西在c++11里面已经有了。比方bind,仅仅只是boost的库的bind比c++11用着感觉要方便。事实上有些东西我自己由于也没实用c++做过什么大的项目。所以不敢乱说,仅仅敢说点建议性的,关于bind就是绑定函数吧。这个。
。
。比方一个函数原型是这样void fun(int a,int b),我们就能够用boost再绑定一下,比方第2个參数我们固定为100。那么就能够这么写boost::function<void(int,int)>
fun1 = boost::bind(fun,_1,100)。这样我们就成功的通过function和bind联合起来用,来绑定了。我们这里说的是一个定值。事实上这里全然能够依据业务需求来换成一个不定的值。
接下来说说regex,这个是今天最头疼的问题,不是由于正則表達式难,正則表達式在曾经我做java的时候用过。感觉还不错啊。可是boost,c++的语法今天实在是令我淡疼,所以我就想,就先这么肤浅的用着吧。有项目要用的时候我们在深入一下也不迟,boost::regex_match这个函数主要是所有匹配匹配整个串,boost::regex_search这个函数能够实现匹配部分哦,比方192.168.0.1。我们能够通过"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"。来匹配出数字啊。结果自然就存在boost::smatch里面啦,另一个boost::regex_replace,这个替换完的会通过返回值返回回来的。
还有thread。事实上c++11就是抄的boost的thread,他俩大同小异。大家能够借助文档啦。
还有智能指针,智能指针大体有3种,scoped,shared,weak,细分的话就是scoped_ptr,scoped_array,同理shared也是,weak仅仅有weak_ptr,scoped的意思就是我们分配了就仅仅能是我自己指向这块内存。不能拷贝赋值,shared能够拷贝赋值。weak_ptr是一个弱引用。为什么说是弱引用呢,事实上并不改动该对象的引用计数。
若引用能够防止内存泄露,不要觉得仅仅能指针就不会内存泄露,c++的内存泄露也是偶尔会存在智能指针里的,举个栗子:
#include <iostream>
#include <boost/smart_ptr.hpp> using namespace std; class Parent;
class Children; class Parent
{
public:
Parent()
{
cout << "parent create" << endl;
}
~Parent()
{
cout << "parent destroy" << endl;
}
boost::shared_ptr<Children> c;
}; class Children
{
public:
Children()
{
cout << "children create" << endl;
}
~Children()
{
cout << "children destroy" << endl;
}
boost::shared_ptr<Parent> p;
}; void test()
{
boost::shared_ptr<Parent> p(new Parent);
boost::shared_ptr<Children> c(new Children);
p->c = c;
c->p = p;
} void main()
{
test();
cin.get();
}
这不就内存泄露了吗。Parent里有指针指向Children。Children内部有指针指向Parent,这俩就在这循环着,谁也不释放内存,假设想结局这个问题。我们就要用到weak_ptr,仅仅要我们将当中一个对象内部的指针从shared_ptr改为weak_ptr就能够了,所以说我们编程的时候,一定要有这个意识。智能指针也会内存泄露。
ref就是一个包装的引用,有的时候我们不能拷贝复制,由于有的时候传參是拷贝传參的,所以这个时候我们就要用到了ref。
unordered里主要是由unordered_map,unordered_mutlimap,unordered_set,unordered_mutliset。他们内部结构都是哈希,查找的时间复杂度为O(1),这个是boost帮我们实现的了。
-----------------------------------------------------------------------------------------------------------切割线-------------------------------------------------------------------------------------------------------------------
以下是设计模式了
外观模式:上图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFuY2hhb2hhbzIwMTI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
这个外观模式的精髓就在于Facade这个类实现的分离。
外观模式就是给client暴露的接口非常少。真正复杂的业务逻辑我们全都缴费Facade和SubSystem来交互。
应用场景:
首先,在设计初期阶段,应该要有意识将不同的两个层分离,,层与层之间建立外观Facade,
其次。在开发阶段,子系统往往由于不断的重构演化而变得越来越复杂。添加外观模式,降低依赖。
第三,维护一个一流的大型系统的时候,可能这个系统已经很难以维护和扩展了,就要改动设计,让新系统与Facade对象交互。Facade与遗留代码交互全部复杂工作。
。。
所以说,建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时使用的模式.
事实上我们在android里的AlertDialog.Builder不也非常相似吗,我们没有关注细节,最后build除了那个dialog
#include <iostream> using namespace std; class Product
{
public :
char *head = nullptr;
char *body = nullptr; friend ostream & operator<<(ostream & os, Product & pro)
{
os << pro.head << " " << pro.body;
return os;
}
}; class Builder
{
protected:
Product *p = nullptr;
public:
Builder()
{
p = new Product;
}
~Builder()
{
delete p;
}
public:
virtual Product & getResult()
{
return *p;
}
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
}; class BuilderA : public Builder
{
public:
virtual void buildPartA() override
{
p->head = "大头";
}
virtual void buildPartB() override
{
p->body = "金身";
}
}; class BuilderB : public Builder
{
public:
virtual void buildPartA() override
{
p->head = "小头";
}
virtual void buildPartB() override
{
p->body = "測试";
}
}; class Director
{
public:
void build(Builder & b)
{
b.buildPartA();
b.buildPartB();
}
}; void main_jianzao()
{
Builder *b1 = new BuilderA;
Builder *b2 = new BuilderB;
Director dir;
dir.build(*b1);
dir.build(*b2);
Product &p1 = b1->getResult();
Product &p2 = b2->getResult();
cout << p1 << endl;
cout << p2 << endl; cin.get();
}
并且他不知道详细有多少对象有待改变的时候,应该考虑使用观察者模式。
观察者模式所做的工作就是在解除耦合.让耦合两方都依赖于抽象,而不是依赖于详细,从而使得各自的变化都不会影响还有一边的变化.
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/smart_ptr.hpp>
#include <memory> using namespace std; class Observer;
class TongshiA;
class TongshiB;
class Event;
template<class T>
class AbstractSubject; class Secretary;
class Boss; class Event
{
public:
string type = nullptr;
string content = nullptr;
Event()
{ }
Event(string &type, string & content) :type(type), content(content)
{ }
}; template<class T>
class AbstractSubject
{
protected:
vector<T *> *obsevers = nullptr; public:
virtual void attch(T * p)
{
obsevers->push_back(p);
}
virtual void detach(T * p)
{
remove(obsevers->begin(), obsevers->end(), p);
}
virtual void notifyall() = 0;
AbstractSubject()
{
obsevers = new vector<T*> ;
}
~AbstractSubject()
{
delete obsevers;
} }; class Observer
{
public:
const char *name;
Observer(const char *name) :name(name)
{ }
virtual void update(Event & e)
{
cout << "消息内容:" << e.content.c_str() << endl;
}
}; class TongshiA : public Observer
{
public:
TongshiA(const char * name) :Observer(name)
{ }
virtual void update(Event & e) override
{
cout << "消息内容:" << e.content.c_str() << endl;
if (strcmp(e.type.c_str(), "警报") == 0)
{
cout << "关闭游戏,继续工作" << endl;
}
else
{
cout << "反正老板也没回来,去刷副本" << endl;
}
}
}; class TongshiB : public Observer
{
public:
TongshiB(const char *name) :Observer(name)
{ }
virtual void update(Event & e) override
{
cout << "消息内容:" << e.content.c_str() << endl;
if (strcmp(e.type.c_str(), "警报") == 0)
{
cout << "最小化股票,好好工作" << endl;
}
else
{
cout << "和同事还能聊会儿天" << endl;
}
}
}; class Secretary : public AbstractSubject<Observer>
{
public: virtual void attch(Observer * t)
{
obsevers->push_back(t);
}
virtual void detach(Observer * t)
{
remove(obsevers->begin(), obsevers->end(), t);
}
virtual void notifyall() override
{
for_each(obsevers->begin(), obsevers->end(), [&](Observer * obs)
{
string s1("警报");
string s2("老板来了");
Event e(s1, s2);
obs->update(e);
});
}
}; class Boss : public AbstractSubject < Observer >
{
public:
virtual void attch(Observer * t)
{
obsevers->push_back(t);
}
virtual void detach(Observer * t)
{
remove(obsevers->begin(), obsevers->end(), t);
}
virtual void notifyall() override
{
for_each(obsevers->begin(), obsevers->end(), [&](Observer * obs)
{
string s1("正常");
string s2("老板出去了");
Event e(s1,s2);
obs->update(e);
});
}
}; void main()
{ AbstractSubject<Observer> *sec = new Secretary;
Observer *a = new TongshiA("tongshia");
Observer *b = new TongshiB("tongshib");
sec->attch(a);
sec->attch(b); AbstractSubject<Observer> *boss = new Boss;
boss->attch(a);
boss->attch(b); sec->notifyall();
cout << "---------------------------------" << endl;
boss->notifyall(); cin.get();
}
2015-03-12---外观模式,建造者模式(附代码),观察者模式(附代码),boost库应用的更多相关文章
- java设计模式--创建模式--建造者模式
对于建造者模式,小编个人理解为就是一个组装型的模式. 建造者模式 概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 适用性 1.当创建复杂对象的算法应该独立于该对象的组 ...
- [19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)
一.建造者模式 本质:分离了对象子组件的单独构造(由Builder负责)和装配的分离(由Director负责),从而可以构建出复杂的对象,这个模式适用于:某个对象的构建过程十分复杂 好处:由于构建和装 ...
- 设计模式01 创建型模式 - 建造者模式(Build Pattern)
参考 1. Builder Design Pattern | Youtube 2. 建造者模式(Builder和Director)| 博客园 3. 深入理解Builder模式 | 简书 建造者模式(B ...
- Builder模式(建造者模式)
在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...
- 2015.03.12,外语,读书笔记-《Word Power Made Easy》 10 “如何讨论交谈习惯”学习笔记 SESSION 25
1.about keeping one's mouth shut taciturn,名词形式taciturnity,沉默寡言. 美国第30任总统库里奇,以沉默寡言著称.他来自新英格兰,那里视tacit ...
- C++设计模式之建造者模式(三)
4.引入钩子方法的建造者模式 建造者模式除了逐步构建一个复杂产品对象外.还能够通过Director类来更加精细地控制产品的创建过程.比如添加一类称之为钩子方法(HookMethod)的特殊方法来控制是 ...
- 设计模式之建造者模式(Builder)
一个人活到70岁以上,都会经历这样的几个阶段:婴儿,少年,青年,中年,老年.并且每个人在各个阶段肯定是不一样的呀,我觉得可以说世界上不存在两个人在人生的这5个阶段的生活完全一样,但是活到70岁以上的人 ...
- java设计模式(二)单例模式 建造者模式
(三)单例模式 单例模式应该是最常见的设计模式,作用是保证在JVM中,该对象仅仅有一个实例存在. 长处:1.降低某些创建比較频繁的或者比較大型的对象的系统开销. 2.省去了new操作符,减少系统内存使 ...
- 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
随机推荐
- BZOJ 1831: [AHOI2008]逆序对
题目大意: 给出一个序列,有几个位置上的数字任意.求最小的逆序对数. 题解: 自己决定放置的数一定是单调不降的.不然把任意两个交换一下就能证明一定会增加逆序对. 然后就可以DP了,f[i][j]表示第 ...
- ASP.NET MVC 通用角色权限管理系统
RightControl 介绍 .NET 通用后台角色权限管理系统,已完成.项目地址:http://106.14.77.184/Admin/Login 码云地址:https://gitee.com/L ...
- CentOS下配置LVM和RAID
1.CentOS配置LVM http://www.cnblogs.com/mchina/p/linux-centos-logical-volume-manager-lvm.html http://ww ...
- Access denied for user ''@'localhost' to database 'mysql'
ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql' 在centos下安装好了mysql,用r ...
- cell左右滑动展开更多按钮-MGSwipeTableCell
MGSwipeTableCell是一个UITableViewCell的子类, 它实现了左,右滑动展开更多按钮用来实现一些相关操作就和QQ好友列表滑动展开的按钮一样,封装的很好,动画效果也处理很到位,废 ...
- 【Luogu】P2530化工厂装箱员(DP)
题目链接 不知道做出这道题是我能力的一个提升还是能力的回归. DP.设f[i][j][k][l]是已经取了i个产品,现在手里还拿着j件A,k件B,l件C,最小的操作数. 然后状转方程乱搞啊 #incl ...
- 【邻接表+匈牙利算法模板】Elementary Math
http://acm.bnu.edu.cn/v3/external/gym/101485.pdf #include<bits/stdc++.h> using namespace std; ...
- angular父子scope之间的访问
1.子可以访问父的scope,也可以更新相同的scope,但父scope不会被刷新 2.父要访问子scope的方法
- Codeforces963D. Frequency of String
$n \leq 100000$的一文本串,给$m \leq 100000$个询问,每次问一小串在文本串的哪一个最短的子串里出现指定次数.注意,询问串互不相同,且总长度$\leq 100000$. 比赛 ...
- Linux 的信号和线程
什么是线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成,每一个程序都至少 ...