基于Linux内核链表实现的模板类,大家看看还有什么值得改进的地方

光谷中心城打工人 2011-11-01 10:29:31

/*******************************************************************************
文件名 : zlist.h
相关文件 :
文件实现功能 : 使用模板类封装linux内核链表
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 创建
*******************************************************************************/


#ifndef ZLIST_H
#define ZLIST_H

#include "list.h"

class ZListNode
{
public:
struct list_head list;
};

template <typename T>
class Zlist
{
public:
Zlist(void)
{
m_iElmCount=0;
INIT_LIST_HEAD(&m_ListHead);
}
// Zlist<T> & oprator=(const Zlist<T> & L );
~Zlist(void)
{
Release();
}
//在表头增加
void Add(T * p)
{
m_iElmCount++;
list_add(&p->list,&m_ListHead);
}
//在表尾增加
void AddTail(T * p)
{
m_iElmCount++;
list_add_tail(&p->list,&m_ListHead);
}
//删除节点
void Delete(T * p)
{
if(m_iElmCount <= 0)
return ;

list_del(&p->list);
m_iElmCount--;
}
bool IsMember(T * p)
{
int index = GetIndex(p);
if (-1 == index)
{
return false;
}
else
{
return true;
}
}
void Delete(int index)
{
T * tmp;

if(index >= m_iElmCount)
return ;

tmp = GetAt(index);
list_del(&tmp->list);
m_iElmCount--;

}
//获取序号为index的节点
T * GetAt(int index)
{
T * tmp;
int i=0;
struct list_head* pos, *q;

if(index >= m_iElmCount)
{
return NULL;
}

list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
if(index == i)
{
return tmp;
}
else
{
i++;
}
}
return NULL;
}

int GetIndex(T * p)
{
int i=0;
struct list_head* pos, *q;

list_for_each_safe(pos,q,&m_ListHead)
{
if( p == list_entry(pos) )
{
return i;
}
else
{
i++;
}
}
return -1;
}
//获取元素个数
inline int GetElmNum()
{
return m_iElmCount;
}
//是否为空
bool IsEmpty()
{
return list_empty_careful(&m_ListHead);
}
void Release()
{
struct list_head* pos, *q;
T * tmp;

list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
list_del(pos);
delete tmp;
tmp = NULL;
}
m_iElmCount = 0;
}//释放链表

private:
struct list_head m_ListHead ;
int m_iElmCount;
T * list_entry(void * ptr)
{
T * tmp;
struct list_head *__mptr = (struct list_head *)(ptr);
tmp = (T *)( (char *) __mptr - offsetof(TestData,list) );
return tmp;
}

};

#endif

...全文
100 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
已毕业程序员 2012-10-09
  • 打赏
  • 举报
回复
写不错,学习了
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lthyxy 的回复:]
厉害。。。
[/Quote]


俺们新手 。大虾请指教。。。
liutengfeigo 2011-11-01
  • 打赏
  • 举报
回复
厉害。。。
LENOVO_ 2011-11-01
  • 打赏
  • 举报
回复
c++ 的 一些特殊语法,比如拷贝构造函数、赋值运算符重载,需要实现。

这个类没有使用 全局或静态成员 , 是安全的。
  • 打赏
  • 举报
回复

/*******************************************************************************
文件名 : Tmeplate_Test.h
相关文件 :
文件实现功能 : 介绍如何使用Linux内核链表模板类ZList
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 创建
*******************************************************************************/

#include "stdafx.h"
#include "zlist.h"


//任何使用ZList的类都需要继承自ZListNode
class TestData :public ZListNode
{
public:
int index;
char szText[5];
} ;

int _tmain(int argc, _TCHAR* argv[])
{
Zlist<TestData> list; //申明链表

TestData * oneData = NULL;

//添加元素
for(int i =0;i <10;i++)
{
TestData * pTD = new TestData;
pTD->index = i;
sprintf(pTD->szText,"%d",i);
//list.Add(pTD); //加入到链表头,使用ListAddTail则添加到尾部
list.AddTail(pTD); //加入到链表尾部

//记录一个元素用来用来演示下面的删除等操作。
if(6 == i)
{
oneData = pTD;
}

}

//获取成员序号,若添加方式是ListAdd,所以对应关系为
//0-9 1-8 2-7 3-6 ,,index应该为3
//若添加方式为ListAddTail,则序号为6
int index = list.GetIndex(oneData);

//查找是否存在某个元素
bool isIn = list.IsMember(oneData);

//遍历列表
TestData * tmp;
for(int j=0;j<list.GetElmNum();j++)
{
tmp = list.GetAt(j);
}

//两种删除方式
list.Delete(0);
list.Delete(oneData);

//查找是否存在某个元素,此元素目前已不在list中
isIn = list.IsMember(oneData);

for(int j=0;j<list.GetElmNum();j++)
{
tmp = list.GetAt(j);
}

list.Release();
return 0;
}


  • 打赏
  • 举报
回复


/*******************************************************************************
文件名 : list.h
相关文件 :
文件实现功能 : linux内核链表的定义
作者 : <linux>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 修改
*******************************************************************************/

#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

/*
#define container_of(ptr, type, member) ( { \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); } )
*/

static inline void prefetch(const void *x) {;}
static inline void prefetchw(const void *x) {;}

#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)

struct list_head {
struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *newelm,
struct list_head *prev,
struct list_head *next)
{
next->prev = newelm;
newelm->next = next;
newelm->prev = prev;
prev->next = newelm;
}

/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *newelm, struct list_head *head)
{
__list_add(newelm, head, head->next);
}

/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *newelm, struct list_head *head)
{
__list_add(newelm, head->prev, head);
}

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}

static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head *)LIST_POISON1;
entry->prev = (struct list_head *)LIST_POISON2;
}

static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}

static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}

static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}

static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}

static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}

static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;

first->prev = head;
head->next = first;

last->next = at;
at->prev = last;
}

/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}

/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
#if 0
#define list_entry(ptr, type, member) container_of(ptr, type, member)
#endif



#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)

#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)

#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
pos = pos->prev)

#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)

#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))

#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))

#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))

#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))

#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))

#endif


  • 打赏
  • 举报
回复

/*******************************************************************************
文件名 : Tmeplate_Test.h
相关文件 :
文件实现功能 : 介绍如何使用Linux内核链表模板类ZList
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.1 <孙志新> 创建
*******************************************************************************/

#include "stdafx.h"
#include "zlist.h"


//任何使用ZList的类都需要继承自ZListNode
class TestData :public ZListNode
{
public:
int index;
char szText[5];
} ;

int _tmain(int argc, _TCHAR* argv[])
{
Zlist<TestData> list; //申明链表

TestData * oneData = NULL;

//添加元素
for(int i =0;i <10;i++)
{
TestData * pTD = new TestData;
pTD->index = i;
sprintf(pTD->szText,"%d",i);
//list.push_front(pTD); //加入到链表头,使用ListAddTail则添加到尾部
list.push_back(*pTD); //加入到链表尾部

//记录一个元素用来用来演示下面的删除等操作。
if(6 == i)
{
oneData = pTD;
}

}

//获取成员序号,若添加方式是ListAdd,所以对应关系为
//0-9 1-8 2-7 3-6 ,,index应该为3
//若添加方式为ListAddTail,则序号为6,返回-1表示没有此元素
//int index = list.GetIndex(oneData);

//查找是否存在某个元素
bool isIn = list.ismember(*oneData);

//遍历列表
TestData * tmp;
for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}

//两种删除方式
list.erase(0);
list.erase(*oneData);

//查找是否存在某个元素,此元素目前已不在list中
isIn = list.ismember(*oneData);

for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}



TestData td_f = list.front();
TestData td_l = list.back();

TestData * pTD_s = new TestData;
pTD_s->index = 6;
sprintf(pTD_s->szText,"%d",6);

list.insert(100,*pTD_s);

for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}

list.clear();
return 0;
}


  • 打赏
  • 举报
回复
更新一下 新版本

/*******************************************************************************
文件名 : zlist.h
相关文件 :
文件实现功能 : 使用模板类封装linux内核链表
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.1 <孙志新> 创建
*******************************************************************************/


#ifndef ZLIST_H
#define ZLIST_H

#include "list.h"

class ZListNode
{
public:
struct list_head list;
};

template <typename T>
class Zlist
{
public:
/************************************************************************
* 名称: Zlist
* 功能: 构造函数
* 输入:
* 返回:
************************************************************************/
Zlist(void)
{
m_iElmCount=0;
INIT_LIST_HEAD(&m_ListHead);
}

/************************************************************************
* 名称: ~Zlist
* 功能: 析构函数
* 输入:
* 返回:
************************************************************************/
~Zlist(void)
{
clear();
}

public:
/************************************************************************
* 名称: push_front
* 功能: 在链表头部插入元素
* 输入: T * ,元素地址
* 返回: void
************************************************************************/
void push_front(T & e)
{
m_iElmCount++;
list_add(&e.list,&m_ListHead);
}

/************************************************************************
* 名称: push_back
* 功能: 在链表尾部插入元素
* 输入: T & ,要增加的元素的引用
* 返回: void
************************************************************************/
void push_back(T & e)
{
m_iElmCount++;
list_add_tail(&e.list,&m_ListHead);
}

/************************************************************************
* 名称: pop_front
* 功能: 删除链表第一个元素
* 输入: 无
* 返回: void
************************************************************************/
void pop_front()
{
remove(0);
}

/************************************************************************
* 名称: pop_back
* 功能: 删除链表最后一个元素
* 输入: 无
* 返回: void
************************************************************************/
void pop_back()
{
remove(m_iElmCount -1);
}

/************************************************************************
* 名称: back
* 功能: 返回链表最后一个元素的引用
* 输入: 无
* 返回: T &
************************************************************************/
T & front()
{
T * first = get_at(0);
return *first;
}

/************************************************************************
* 名称: back
* 功能: 返回链表最后一个元素的引用
* 输入: 无
* 返回: T &
************************************************************************/
T & back()
{
T * last = get_at(m_iElmCount -1);
return *last;
}

/************************************************************************
* 名称: insert
* 功能: 在链表指定位置插入一个元素
* 输入: int,插入的位置,如果loc 大于等于当前元素个数,此时相当于调用push_back
* 当loc <=0 ,相当于调用push_front
* 输入: const T & ,要插入的元素
* 返回: T &
************************************************************************/
void insert(int loc,T & e)
{
T * tmp;
int i=0;
struct list_head* pos, *q;

if(loc <= 0)
{
push_front(e);
return ;
}

if(loc >= m_iElmCount)
{
push_back(e);
return ;
}

list_for_each_safe(pos,q,&m_ListHead)
{
if(loc == i)
{
tmp= list_entry(pos);
list_add(&e.list,pos->prev);
return ;
}
else
{
i++;
}
}
}

/************************************************************************
* 名称: remove
* 功能: 在链表删除指定元素,元素内存由用户自己释放
* 输入: T & ,要删除的元素的引用
* 返回: void
************************************************************************/
void erase(T & e)
{
if(m_iElmCount <= 0)
return ;

list_del(&e.list);
// delete &e;
m_iElmCount--;
}

/************************************************************************
* 名称: remove
* 功能: 在链表删除指定元素
* 输入: int ,要删除的元素在链表中得序号
* 返回: void
************************************************************************/
void erase(int index)
{
T * tmp;

if(index >= m_iElmCount)
return ;

tmp = get_at(index);
list_del(&tmp->list);
//delete tmp;
m_iElmCount--;
}

/************************************************************************
* 名称: ismember
* 功能: 判断元素是否是存在于list
* 输入: const T & ,要进行判断的元素
* 返回: bool
************************************************************************/
bool ismember(const T & e)
{
int index = index_of(&e);
if (-1 == index)
{
return false;
}
else
{
return true;
}
}

/************************************************************************
* 名称: size
* 功能: 返回当前链表中元素的个数
* 输入: 无
* 返回: int ,元素个数
************************************************************************/
inline int size()
{
return m_iElmCount;
}

/************************************************************************
* 名称: empty
* 功能: 判断当前链表是否为空
* 输入: 无
* 返回: bool
************************************************************************/
bool empty()
{
return list_empty_careful(&m_ListHead);
}

/************************************************************************
* 名称: clear
* 功能: 删除链表中所有的元素
* 输入: 无
* 返回: void
************************************************************************/
void clear()
{
struct list_head* pos, *q;
T * tmp;

list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
list_del(pos);
delete tmp;
tmp = NULL;
}
m_iElmCount = 0;
}

/************************************************************************
* 名称: get_at
* 功能: 获取链表中指定序号的元素
* 输入: 无
* 返回: T &
************************************************************************/
T * get_at(int index)
{
T * tmp;
int i=0;
struct list_head* pos, *q;

if(index >= m_iElmCount)
{
return NULL;
}

list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
if(index == i)
{
return tmp;
}
else
{
i++;
}
}
return NULL;
}

/************************************************************************
* 名称: index_of
* 功能: 获取链表中指定元素的序号
* 输入: const T * ,元素地址
* 返回: int ,序号,返回-1表示list中不存在此元素
************************************************************************/
int index_of(const T * p)
{
int i=0;
struct list_head* pos, *q;

list_for_each_safe(pos,q,&m_ListHead)
{
if( p == list_entry(pos) )
{
return i;
}
else
{
i++;
}
}
return -1;
}

private:
T * list_entry(void * ptr)
{
T * tmp;
struct list_head *__mptr = (struct list_head *)(ptr);
tmp = (T *)( (char *) __mptr - offsetof(TestData,list) );
return tmp;
}

private:
struct list_head m_ListHead;
int m_iElmCount;
};

#endif

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧