C++primer中 CacheObj实现(非常有意思)
//CacheObj.h #ifndef __CacheObj__
#define __CacheObj__ #include <iostream>
#include <stdexcept>
#include <malloc.h> /*
* memory allocation class: Pre-allocates objects and
* maintains a freelist of objects that are unused
* When an object if freed, it is put back on the freelist
* some of the memory will be only returned when the program exist;
*/
template < typename Type >
class CacheObj
{
public:
static void* operator new(std::size_t);
#if 1
static void* operator new[](std::size_t);
#endif static void operator delete(void*, std::size_t);
#if 1
static void operator delete[](void*, std::size_t);
#endif virtual ~CacheObj(){} protected:
Type *next;
static void list_free(void); private:
static void add_to_freelist(Type *);
static Type* freelist;
static std::size_t unuse_size; //未用链表的长度不会超过2 * chunk;
static const std::size_t chunk;
}; template < typename Type > Type* CacheObj< Type >::freelist = NULL;
template < typename Type > std::size_t CacheObj< Type >::unuse_size = ;
template < typename Type > const std::size_t CacheObj< Type >::chunk = ; template < typename Type >
void* CacheObj< Type >::operator new(std::size_t size)
{
/*
* new should only be asked to build a Type;
* not an object derived from T;
* check that right size is requested
*/
if(size != sizeof(Type))
{
throw std::runtime_error("CacheObj: wrong size object in operator new");
} //if list is empty: grab a new chunk of memory
//allocate allocates chunk number of objects of type Type
if(NULL == freelist)
{
#if 0
//一次申请大量数据空间,很爽啊,可是因为这种不计后果的行为,花费了大半天的时间
/*解释:
*很明显的bug例子:int *p = (int*)malloc(8*sizeof(int)); free(p); free(p+4);
*自己考虑的太不周全了
*使用一次性申请大量空间的bug出在:
* list_free()函数,其中每次free都以一个object的地址为参数,如同给出的bug示例,所以错了
*
*/
Type* array = (Type*)malloc(size * chunk);
if(NULL == array)
{
throw std::runtime_error("CacheObj: wrong size object in operator new");
}
//谢谢陈涛,大神走了还有个人讨论,终于发现问题的所在了
#endif //allocate allocates chunk number of objects of type T
for(unsigned int i = ; i != chunk; i++)
{
#if 1
Type* array = (Type*)malloc(size);
if(NULL == array)
{
throw std::runtime_error("CacheObj: wrong size object in operator new");
}
#endif
add_to_freelist(array);
#if 0
array++;
#endif
}
} Type *p = freelist;
freelist = freelist->CacheObj< Type >::next;
unuse_size--;
p->CacheObj< Type >::next = NULL;
return p;
} #if 1
template < typename Type >
void* CacheObj< Type >::operator new[](std::size_t size)
{
void *p = malloc(size);
return p;
}
#endif template <typename Type >
void CacheObj< Type >::operator delete(void* p, std::size_t)
{
if(p != )
{
add_to_freelist(static_cast< Type* >(p));
}
} #if 1
template < typename Type >
void CacheObj< Type >::operator delete[](void* p, std::size_t)
{
if(!p)
free(p);
}
#endif template < typename Type >
void CacheObj< Type >::list_free(void)
{
while(freelist)
{
Type *temp = freelist;
freelist = temp->CacheObj< Type >::next;
free(temp);
unuse_size--;
}
} //puts object at head of the freelist
template < typename Type >
void CacheObj< Type >::add_to_freelist(Type *p)
{
if(!p)
return; if(unuse_size >> == chunk)
{
free(p);
return ;
} unuse_size++;
p->CacheObj< Type >::next = freelist;
freelist = p;
} #endif
//QueueItem.h #ifndef __QUEUEITEM__
#define __QUEUEITEM__ #include "CacheObj.h" template < typename Type > class Queue; //下面因为进行类模板特化,所以此处先声明 template < typename Type >
std::ostream& operator<<(std::ostream&, const Queue< Type >&); //下面需要进行函数模特化,所以此处先声明 template < typename Type >
class QueueItem: public CacheObj< QueueItem< Type > >
{
friend class Queue< Type >; //类模板特化
friend std::ostream& operator<< < Type >(std::ostream&, const Queue< Type >&); //函数模板特化
//private class : no public section; QueueItem(const Type &t): item(t), next(){} Type item; //value stored in this element;
QueueItem *next; //pointer to next element in the Queue; ~QueueItem(void)
{
next = NULL;
}
}; template < typename Type >
class Queue
{
friend std::ostream& operator<< < Type >(std::ostream&, const Queue< Type >&); //函数模板特化
public:
//empty Queue
Queue(void):head(), tail(){} //copy control to manage pointers to QueueItems in the Queue
Queue(const Queue &Q):head(), tail()
{
copy_elems(Q);
} template < typename Iter >
Queue(Iter beg, Iter end); //成员模板 ~Queue(void); Queue& operator=(const Queue&); Type& front(void); const Type& front(void) const; //return element from head of Queue; void push(const Type&); //add element to back of Queue;
void pop(void); //remove element from head of Queue;
bool empty(void)const; //true if no elements in Queue; private:
QueueItem< Type >* head; //pointer to first element in Queue;
QueueItem< Type >* tail; //pointer to last element in Queue; //utility functions used by copy constructor, assignment, and destructor
void destroy(void); //delete all the elements;
void copy_elems(const Queue&); //copy elements from parameter template < typename Iter >
void copy_elems(Iter beg, Iter end); //成员模板,且重载上一函数
}; //成员模板实现
template < typename Type >
template < typename Iter >
Queue< Type >::Queue(Iter beg, Iter end):head(), tail()
{
destroy();
copy_elems(beg, end);
} template < typename Type >
Queue< Type >::~Queue(void)
{
destroy();
} template < typename Type >
Queue< Type >& Queue< Type >::operator=(const Queue<Type>& src)
{
Queue< Type >* pt = head;
if(head != )
{
while(pt)
{
QueueItem< Type >* temp = pt;
pt = pt->next;
delete temp;
}
} head = tail = ;
copy_elems(src);
} template < typename Type >
Type& Queue< Type >::front(void)
{
return head->item;
} template < typename Type >
const Type& Queue< Type >::front(void) const
{
return head->item;
} template < typename Type >
void Queue< Type >::push(const Type& val)
{
//allocate a new QueueItem object;
QueueItem< Type >* pt = new QueueItem< Type >(val); //put item onto existing queue;
if(empty())
{
head = tail = pt; //the queue now has only one element;
}
else
{
tail->next = pt; //add new element to end of the queue;
tail = pt;
}
} //pop is unchecked: Popping off an empty Queue is undefined;
template < typename Type >
void Queue< Type >::pop(void)
{
QueueItem< Type >* p = head; //keep pointer to head so we can delete it;
head = head->next; //head now points to next element;
delete p; //delete old head element;
} template < typename Type >
bool Queue< Type >::empty(void)const
{
return head == ;
} //成员函数实现
template < typename Type >
void Queue< Type >::destroy(void)
{
while(!empty())
pop(); QueueItem< Type >::list_free();
} //copy elements from orig into this Queue;
//loop stops when pt == 0, which happens when we reach orig.tail;
template < typename Type >
void Queue< Type >::copy_elems(const Queue< Type >& orig)
{
for(QueueItem< Type >*pt = orig.head; pt = pt->next;)
{
push(pt->item);
}
} //成员模板实现
template < typename Type >
template < typename Iter >
void Queue< Type >::copy_elems(Iter beg, Iter end)
{
while(beg != end)
{
push(*beg);
++beg;
}
} //普通函数模板
template < typename Type >
std::ostream& operator<<(std::ostream &os, const Queue< Type >& q)
{
os << "< ";
QueueItem< Type >*p; for(p = q.head; p ; p = p->next)
{
os << p->item << " ";
}
os << ">";
return os;
} #endif
//test.cpp #include <iostream>
#include "QueueItem.h" int main(void)
{
int array[] = {, , , , };
Queue<int> qi(array + , array + );
short s = ;
qi.push(s);
qi.pop();
qi.pop();
qi.pop();
qi.push(s);
qi.push(s);
std::cout << qi << std::endl; return ;
}
C++primer中 CacheObj实现(非常有意思)的更多相关文章
- c++ primer 中讲的顶层const 和 底层 const 理解
c++ primer 中讲的 顶层const 和 底层 const 以前没搞懂的顶层const和底层const,这次看了后感觉明白了. 首先,const是一个限定符,被它修饰的变量的值不能改 ...
- C++primer中的TextQuery(读取文本)
本题目对应于 C++primer(第四版)中 第十章的文本查询类(TextQuery) 用到的知识有: 顺序容器 vector 关联容器 set,map 标准输入输出流,文件流,字符串流 //写一个文 ...
- 总结c++ primer中的notes
转载:http://blog.csdn.net/ace_fei/article/details/7386517 说明: C++ Primer, Fourth Edition (中英文)下载地址:htt ...
- C++ Primer中文本查询演示样例Query的实现
近期在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询演示样例时,认为设计得非常不错,于是便动手照着实现了一个,改动了非常久最终执行成功了,从中也学习到了非常多的语法.以下把实现 ...
- 功能测试中遇到的一些有意思的bug
2016.1.25 1. Xss攻击型的bug Xss攻击即跨站脚步攻击,通过插入恶意脚本 ,实现对用户浏览器的控制. Bug现象:新增物品时,物品名称输入一段JavaScript代码,在提交时此代 ...
- 【Python】Python中对象管理与垃圾回收中两个很有意思的问题
再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两 ...
- C++Primer中for(auto it=s.cbegin(); iter!=s.cend() && !it->empty(); ++it){ cout<<*it<<endl; }有错误
在C++ Primer 中文版 第五版的 98页 ,有这么一段代码 for(auto it=text.cbegin(); it!=text.cend() && !it->empt ...
- 【转】 C#中Finally的一个不太常见的用法
原文地址:http://www.cnblogs.com/listhome/p/3664300.html 最近在看.net BCL 传送门 的源码. 在 System.Collections.Concu ...
- C#中Finally的一个不太常见的用法
最近在看.net BCL 传送门 的源码. 在 System.Collections.Concurrent.ConcurrentQueue 中看到一段有意思的代码.注意这段代码是写在Concurren ...
随机推荐
- mysql执行计划介绍
简单讲讲mysql的执行计划,只列出了一些常见的情况,希望对大家有所帮助 烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长.如何写好sql,学会看执行计划至 ...
- js+json用表格实现简单网站左侧导航
闲暇之余,制作一用表格实现的简单的网站导航条,分享给大家.这里的数据基于json格式,学习json的朋友可以参考下. 调用很简单,只要将数据组织成json格式即可:格式如下: window.onlo ...
- UIActivityIndicatorView的详细使用
转自:http://www.cnblogs.com/top5/archive/2012/05/17/2506623.html UIActivityIndicatorView实例提供轻型视图,这些视图显 ...
- 每日英语:China's Retirement Age Sets Experts at Odds
The politically explosive issue of the official retirement age has drawn academics from two of China ...
- iOS Emoji
iOS Emoji 前言:我比较喜欢有趣的东西,有一些有趣的小东西,可能不是多么多么牛逼,也可能不需要多高深的技巧,也不会为其他什么强大的功能而服务,但是有时候将很多有趣的小东西组合起来运用,比如在你 ...
- hbase RowFilter如何根据rowkey查询以及实例实现代码 habase模糊查询【转】
RowFilter用于过滤row key Operator Description LESS 小于 LESS_OR_EQUAL 小于等于 [EQUAL 等于 NOT_EQUAL 不等于 GREATER ...
- windows党码农在linux下你最需要的软件列表TOP10
NO 10.QQ 神奇的TX,经常更新接口,使得linux社区的模仿软件总是跟不上步伐,一整就不能登陆使用.可是老大,您怎么自从2009-01-04发布了第一版QQ for Linux 1.0 Bet ...
- jquery 给每个li增加事件
<ul id = "list-unstyled"> <li>aaa</li> <li>bbb</li> <li&g ...
- 自定义maven变量以及maven内置常量
本文转自:http://zheng12tian.iteye.com/blog/1770909 在创建Maven工程后,插件配置中通常会用到一些Maven变量,因此需要找个地方对这些变量进行统一定义,下 ...
- 【WPF】一组CheckBox的全选/全不选功能
需求:给一组CheckBox做一个全选/全不选的按钮. 思路:CheckBox不像RadioButton那样拥有GroupName属性来分组,于是我想的方法是将这组CheckBox放到一个布局容器中, ...