:
string, AbstractFactory*>:
:
const_iterator it = _map.find(className);
13. if (it !
= _map.end())
14. return it->second->createInstance();
15. else
16. throw NotFoundException(className);
17. }
18.}
DynamicFactory类在找个合适的类工厂后,就把任务交给了类AbstractFactory去完成。
下面是使用动态类工厂的一个例子:
[cpp] viewplaincopy
1.#include "Poco/DynamicFactory.h"
2.#include "Poco/SharedPtr.h"
3.using Poco:
:
DynamicFactory;
4.using Poco:
:
SharedPtr;
5.class Base
6.{
7.};
8.class A:
public Base
9.{
10.};
11.class B:
public Base
12.{
13.};
14.
15.int main(int argc, char** argv)
16.{
17. DynamicFactory factory;
18. factory.registerClass("A"); // creates Instantiator
19. factory.registerClass("B"); // creates Instantiator
20. SharedPtr pA = factory.createInstance("A");
21. SharedPtr pB = factory.createInstance("B");
22. // you can unregister classes
23. factory.unregisterClass("B");
24. // you can also check for the existence of a class
25. bool haveA = factory.isClass("A"); // true
26. bool haveB = factory.isClass("B"); // false (unregistered)
27. bool haveC = factory.isClass("C"); // false (never registered)
28. return 0;
29.}
由于在Poco中用Poco:
:
Instantiator类创建对象时使用的是类对象的默认构造函数,所以对于类创建时期望不使用默认构造函数或者对构造函数有一些特殊初始化过程要求的情况,用户必须自己实现抽象构造工厂。
下面是其一个例子:
[cpp] viewplaincopy
1.#include "Poco/DynamicFactory.h"
2.using Poco:
:
DynamicFactory;
3.using Poco:
:
AbstractInstantiator;
4.class Base
5.{
6.};
7.class A:
public Base
8.{
9.};
10.class C:
public Base
11.{
12.public:
13. C(int i):
_i(i)
14. {}
15.private:
16. int _i;
17.};
18.
19.class CInstantiator:
public AbstractInstantiator
20.{
21.public:
22. CInstantiator(int i):
_i(i)
23. {}
24. Base* createInstance() const
25. {
26. return new C(_i);
27. }
28.private:
29. int _i;
30.};
31.
32.int main(int argc, char** argv)
33.{
34. DynamicFactory factory;
35. factory.registerClass("A");
36. factory.registerClass("C", new CInstantiator(42));
37. return 0;
38.}
最后给出 AbstractFactory模块的类图:
6.内存池(MemoryPools)
同以往看过的内存池比较,Poco中内存池相当简单。
既不支持对象的分配,也不对内存块大小进行分级,并且释放后的内存的合并策略也很简单。
但这绝不是说它简陋,对于大多数情况,我觉得其完全够用了。
同AutoReleasePool比较,两者的不同之处在于,AutoReleasePool中内存的分配是交由用户进行的,AutoReleasePool只负责释放,而MemoryPool的思想是,内存的分配和释放都由其管理。
首先来回顾一下内存池的作用:
1.解决应用程序频繁申请和释放内存带来的执行效率问题
2.解决内存碎片问题
下面是Poco中内存池函数调用的一些特性:
1. Poco:
:
MemoryPool使用std:
:
vector维护了一组固定大小的内存块指针,每个内存块大小都相等
2.可以通过MemoryPool:
:
get()获得一个内存块的指针,如果池中内存块不够时,一个新的内存块会被分配。
但当池中内存块数目到达池定义的上限时,一个OutOfMemoryException异常会被抛出。
3.调用MemoryPool:
:
release(void*ptr)将把内存块释放入池中
其头文件中的定义如下:
[cpp] viewplaincopy
1.class Foundation_API MemoryPool
2. /// A simple pool for fixed-size memory blocks.
3. ///
4. /// The main purpose of this class is to speed-up
5. /// memory allocations, as well as to reduce memory
6. /// fragmentation in situations where the same blocks
7. /// are allocated all over again, such as in server
8. /// applications.
9. ///
10. /// All allocated blocks are retained for future use.
11. /// A limit on the number of blocks can be specified.
12. /// Blocks can be preallocated.
13.{
14.public:
15. MemoryPool(std:
:
size_t blockSize, int preAlloc = 0, int maxAlloc = 0);
16. /// Creates a MemoryPool for blocks with the given blockSize.
17. /// The number of blocks given in preAlloc are preallocated.
18.
19. ~MemoryPool();
20.
21. void* get();
22. /// Returns a memory block. If there are no more blocks
23. /// in the pool, a new block will be allocated.
24. ///
25. /// If maxAlloc blocks are already allocated, an
26. /// OutOfMemoryException is thrown.
27.
28. void release(void* ptr);
29. /// Releases a memory block and returns it to the pool.
30.
31. std:
:
size_t blockSize() const;
32. /// Returns the block size.
33.
34. int allocated() const;
35. /// Returns the number of allocated blocks.
36.
37. int available() const;
38. /// Returns the number of available blocks in the pool.
39.
40.private:
41. MemoryPool();
42. MemoryPool(const MemoryPool&);
43. MemoryPool& operator = (const MemoryPool&);
44.
45. enum
46. {
47. BLOCK_RESERVE = 128
48. };
49.
50. typedef std:
:
vector BlockVec;
51.
52. std:
:
size_t _blockSize;
53. int _maxAlloc;
54. int _allocated;
55. BlockVec _blocks;
56. FastMutex _mutex;
57.};
其中_maxAlloc是内存池可分配的最大内存块数,_blockSize是每个内存块的大小。
下面是内存池的一个例子:
[cpp] viewplaincopy
1.#include "Poco/MemoryPool.h"
2.#include
3.#include
4.using Poco:
:
MemoryPool;
5.int main(int argc, char** argv)
6.{
7. MemoryPool pool(1024); // unlimited number of 1024 byte blocks
8. // MemoryPool pool(1024, 4, 16); // at most 16 blocks; 4 preallocated
9. char* buffer = reinterpret_cast(pool.get());
10. std:
:
cin.read(buffer, pool.blockSize());
11. std:
:
streamsize n = std:
:
cin.gc