今天白天主要看了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帮我们实现的了。
-----------------------------------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------------------------------
下面是设计模式了
外观模式:上图:
这个外观模式的精髓就在于Facade这个类实现的分离。
外观模式就是给客户端暴露的接口很少,真正复杂的业务逻辑我们全都缴费Facade和SubSystem来交互。
应用场景:
其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。增加外观模式,减少依赖。
第三,维护一个一流的大型系统的时候,可能这个系统已经非常难以维护和扩展了,就要修改设计,让新系统与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();
}