C++设计模式基础教程(4)

2018-11-17 18:52

16

2.2.7程序并发机制扩展阅读

程序的并发执行往往带来与时间有关的错误,甚至引发灾难性的后果。这需要 引入同步机制。使用多进程与多线程时,有时需要协同两种或多种动作,此过程就 称同步(Synchronization)。引入同步机制的第一个原因是为了控制线程之间的资源 同步访问,因为多个线程在共享资源时如果发生访问冲突通常会带来不正确的后果。 例如,一个线程正在更新一个结构,同时另一个线程正试图读取同一个结构。结果, 我们将无法得知所读取的数据是新的还是旧的,或者是二者的混合。第二个原因是 有时要求确保线程之间的动作以指定的次序发生,如一个线程需要等待由另外一个 线程所引起的事件。 为了在多线程程序中解决同步问题,Windows提供了四种主要的同步对象, 每种对象相对于线程有两种状态——信号状态(signal state)和非信号状态(nonsignal state)。当相关联的同步对象处于信号状态时,线程可以执行(访问共享资源),反 之必须等待。这四种同步对象是: (1)事件对象(Event)。事件对象作为标志在线程间传递信号。一个或多个线 程可等待一个事件对象,当指定的事件发生时,事件对象通知等待线程可以开始执 行。它有两种类型:自动重置(auto-reset)事件和手动重置(manual-reset)事件。 (2)临界区(Critical Section)。临界区对象通过提供一个进程内所有线程必须 共享的对象来控制线程。只有拥有那个对象的线程可以访问保护资源。在另一个线 程可以访问该资源之前,前一个线程必须释放临界区对象,以便新的线程可以索取 对象的访问权。 (3)互斥量(Mutex Semaphore)。互斥量的工作方式非常类似于临界区,只是 互斥量不仅保护一个进程内为多个线程使用的共享资源,而且还可以保护系统中两 个或多个进程之间的的共享资源。 (4)信号量(Semaphore)。信号量可以允许一个或有限个线程访问共享资源。 它是通过计数器来实现的,初始化时赋予计数器以可用资源数,当将信号量提供给 一个线程时,计数器的值减1,当一个线程释放它时,计数器值加1。当计数器值小 于等于0时,相应线程必须等待。信号量是Windows98同步系统的核心。从本质上 讲,互斥量是信号量的一种特殊形式。 Windows/NT还提供了另外一种Windows95没有的同步对象:可等待定时器 (Waitable Timer)。它可以封锁线程的执行,直到到达某一具体时间。这可以用于 后台任务。 同步问题是多线程编程中最复杂的问题,后面的linux系统编程中,还会有更深入的介绍。

2.2.8总结

在很多人印象中,单例模式可能是23个设计模式中最简单的一个。如果不考虑多线程,的 确如此,但是一旦要在多线程中运用,那么从我们的教程中可以了解到,它涉及到很多编

译器,多线程,C++语言标准等方面的内容。本专题参考的资料如下:

1、C++ Primer (Stanley B.Lippman),主要参考的是模板静态变量的初始化以及实例化。

17

2、 MSDN,有关线程同步interlocked相关的知识。

3、Effective C++ 04条款(Scott Meyers) Non-Local-Static对象初始化顺序以及Meyers 单例模式的实现。

4、Double-Checked Locking,Threads,Compiler Optimizations,and More(Scott Meyers),解释了由于编译器的优化,导致auto_ptr.reset函数不安全,shared_ptr 有类似情况。我们避免使用reset函数。 5、C++全局和静态变量初始化顺序的研究(CSDN)。 6、四人帮的经典之作:设计模式 7、windows 核心编程(Jeffrey Richter)

2.2简单工厂模式

2.2.1什么是简单工厂模式

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2.2.2模式中包含的角色及其职责

1.工厂(Creator)角色

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。 2.抽象(Product)角色

简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。 3.具体产品(Concrete Product)角色

简单工厂模式所创建的具体实例对象

//依赖: 一个类的对象 当另外一个类的函数参数 或者是 返回值 3简单工厂模式的优缺点

在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,

18

可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

2.2.3案例

include %using namespace std; //思想: 核心思想是用一个工厂,来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。 //元素分析: //抽象产品类:水果类 //具体的水果了:香蕉类、苹果类、梨子 //优点 适用于不同情况创建不同的类时 //缺点 客户端必须要知道基类和工厂类,耦合性差 增加一个产品,需要修改工厂类 class Fruit { public: virtual void getFruit() = 0; protected: private: }; class Banana : public Fruit { public: virtual void getFruit() { cout<<\香蕉\ } protected: private: }; class Pear : public Fruit { public: virtual void getFruit() { 19

cout<<\梨子\ } protected: private: }; class Factory { public: static Fruit* Create(char *name) { Fruit *tmp = NULL; if (strcmp(name, \ { tmp = new Pear(); } else if (strcmp(name, \ { tmp = new Banana(); } else { return NULL; } return tmp; } protected: private: }; void main41() { Fruit *pear = Factory::Create(\ if (pear == NULL) { cout<<\创建pear失败\\n\ } pear->getFruit(); Fruit *banana = Factory::Create(\ banana->getFruit(); system(\20

} 2.2.4练习

主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。 GOOD:适用于不同情况创建不同的类时 BUG:客户端必须要知道基类和工厂类,耦合性差 (工厂类与基类为关联关系) #include %using namespace std; //需求://模拟四则运算; //用操作符工厂类生产操作符(加减乘除), 进行结果运算 //运算符抽象类 COperation //加减乘除具体的类 (注意含有2个操作数) //工厂类CCalculatorFactory //核心思想 用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果 class COperation { public: int first; int second; public: virtual double GetResult() = 0;


C++设计模式基础教程(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:二类城市语言文字学校迎检工作要点及分工

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: