当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

在C/C++中若何构造通用的对象链表[VC/C++编程]

赞助商链接



  本文“在C/C++中若何构造通用的对象链表[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

一个简化的问题示例

链表的难点在于必须复制链表处理函数来处理差别的对象,即便逻辑是完好相同的.比方两个构造近似的链表:

struct Struct_Object_A
{
  int a;
  int b;
  Struct_Object_A *next;
}OBJECT_A;
typedef struct Struct_Object_B
{
  int a;
  int b;
  int c;
  Struct_Object_B *next;
}OBJECT_B;

上面定义的两个构造只有很小的一点差别.OBJECT_B 和 OBJECT_A 之间只差一个整型变量.但是,在编译器看来,它们仍旧是非常差别的.必须为存储在链表中的每个对象复制用来增添、删除和搜索链表的函数.为了办理这个问题,可以利用具有全部三个变量的一个结合或构造,此中整数 c 并非在全部的情形下都要利用.这大概变得非常复杂,并会形成不良的编程气势.

C 代码办理筹划:虚拟链表

此问题更好的办理筹划之一是虚拟链表.虚拟链表是只包含链表指针的链表.对象存储在链表构造背后.这一点是这样实现的,首先为链表节点分配内存,接着为对象分配内存,然后将这块内存分配给链表节点指针,以下所示:

虚拟链表构造的一种实现

typedef struct liststruct
{
  liststruct *next;
}LIST, *pLIST;
pLIST Head = NULL;
pLIST AddToList(pLIST Head, void * data, size_t datasize)
{
  pLIST newlist = NULL;
  void *p;
  // 分配节点内存和数据内存
  newlist = (pLIST) malloc(datasize + sizeof(LIST));
  // 为这块数据缓冲区指定一个指针
  p = (void *)(newlist + 1);
  // 复制数据
  memcpy(p, data, datasize);
  // 将这个节点指定给链表的表头
  if(Head)
    newlist->next = Head;
  else
    newlist->next = NULL;
  Head = newlist;
  return Head;
}

链表节点目前成立在数据值副本的基本之上.这个版本能很好地处理标量值,但不能处理带有效 malloc 或 new 分配的元素的对象.要处理这些对象,LIST 构造需求包含一个普通的解除函数指针,这个指针可用来在将节点从链表中删除并解除它之前释放内存(大概关闭文件,大概调用关闭办法).

一个带有解除函数的链表

typedef void (*ListNodeDestructor)(void *);
typedef struct liststruct
{
  ListNodeDestructor DestructFunc;
  liststruct *next;
}LIST, *pLIST;
pLIST AddToList(pLIST Head, void * data, size_t datasize, ListNodeDestructor Destructor)
{
  pLIST newlist = NULL;
  void *p;
  // 分配节点内存和数据内存
  newlist = (pLIST)malloc(datasize + sizeof(LIST));
  // 为这块数据缓冲区指定一个指针
  p = (void *)(newlist + 1);
  // 复制数据
  memcpy(p, data, datasize);
  newlist->DestructFunc = Destructor;
  // 将这个节点指定给链表的表头
  if(Head)
    newlist->next = Head;
  else
    newlist->next = NULL;
  Head = newlist;
  return Head;
}
void DeleteList(pLIST Head)
{
  pLIST Next;
  while(Head)
  {
    Next = Head->next;
    Head->DestructFunc((void *) Head);
    free(Head);
    Head = Next;
  }
}
typedef struct ListDataStruct
{
  LPSTR p;
}LIST_DATA, *pLIST_DATA;
void ListDataDestructor(void *p)
{
  // 对节点指针举行范例转换
  pLIST pl = (pLIST)p;
  // 对数据指针举行范例转换
  pLIST_DATA pLD = (pLIST_DATA)(pl + 1);
  delete pLD->p;
}
pLIST Head = NULL;
void TestList()
{
  pLIST_DATA d = new LIST_DATA;
  d->p = new char[24];
  strcpy(d->p, "Hello");
  Head = AddToList(Head, (void *)d, sizeof(pLIST_DATA), ListDataDestructor);
  // 该对象已被复制,目前删除本来的对象
  delete d;
  d = new LIST_DATA;
  d->p = new char[24];
  strcpy(d->p, "World");
  Head = AddToList(Head, (void *)d, sizeof(pLIST_DATA), ListDataDestructor);
  delete d;
  // 释放链表
  DeleteList(Head);
}


  以上是“在C/C++中若何构造通用的对象链表[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • 高配置机械在CC攻击需求做的调整
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .