亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

教您在C/C++中如何構造通用的對象鏈表

2019-11-17 05:34:41
字體:
來源:轉載
供稿:網友

  一個簡化的問題示例

鏈表的難點在于必須復制鏈表處理函數來處理不同的對象,即便邏輯是完全相同的。例如兩個結構類似的鏈表:

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;}elsenewlist->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;}elsenewlist->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++ 解決方案:類鏈表

本解決方案將 CList 類定義為從 LIST 結構導出的一個類,它通過存儲解除函數的單個值來處理單個存儲類型。請注重添加的 GetCurrentData() 函數,該函數完成從鏈表節點指針到數據偏移指針的數學轉換。一個虛擬鏈表對象

// 定義解除函數指針typedef void (*ListNodeDestructor)( void * );// 未添加解除函數指針的鏈表typedef struct ndliststruct{ndliststruct *next;} ND_LIST, *pND_LIST;// 定義處理一種數據類型的鏈表類class CList : public ND_LIST{public:CList(ListNodeDestructor);~CList();pND_LIST AddToList( void * data, size_t datasize );void *GetCurrentData();void DeleteList( pND_LIST Head );PRivate:pND_LIST m_HeadOfList;pND_LIST m_CurrentNode;ListNodeDestructorm_DestructFunc;};// 用正確的起始值構造這個鏈表對象CList::CList(ListNodeDestructor Destructor): m_HeadOfList(NULL), m_CurrentNode(NULL){m_DestructFunc = Destructor;}// 在解除對象以后刪除鏈表CList::~CList(){DeleteList(m_HeadOfList);}// 向鏈表中添加一個新節點pND_LIST CList::AddToList( void * data, size_t datasize ){pND_LIST newlist=NULL;void *p;// 分配節點內存和數據內存newlist = (pND_LIST) malloc( datasize + sizeof( ND_LIST ) );// 為這塊數據緩沖區指定一個指針p = (void *)( newlist + 1 );// 復制數據memcpy( p, data, datasize );// 將這個節點指定給鏈表的表頭if( m_HeadOfList ){newlist->next = m_HeadOfList;}elsenewlist->next = NULL;m_HeadOfList = newlist;return m_HeadOfList;}// 將當前的節點數據作為 void 類型返回,以便調用函數能夠將它轉換為任何類型void * CList::GetCurrentData(){return (void *)(m_CurrentNode+1);}// 刪除已分配的鏈表void CList::DeleteList( pND_LIST Head ){pND_LIST Next;while( Head ){Next = Head->next;m_DestructFunc( (void *) Head );free( Head );Head = Next;}}// 創建一個要在鏈表中創建和存儲的結構typedef struct ListDataStruct{LPSTR p;
} LIST_DATA, *pND_LIST_DATA;// 定義標準解除函數void ClassListDataDestructor( void *p ){// 對節點指針進行類型轉換pND_LIST pl = (pND_LIST)p;// 對數據指針進行類型轉換pND_LIST_DATA pLD = (pND_LIST_DATA)( pl + 1 );delete pLD->p;}// 測試上面的代碼void MyCListClassTest(){// 創建鏈表類CList* pA_List_of_Data =new CList(ClassListDataDestructor);// 創建數據對象pND_LIST_DATA d = new LIST_DATA;d->p = new char[24];strcpy( d->p, "Hello" ); // 創建

上一篇:進制的轉換

下一篇:教學計劃編制問題

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩一区二区在线视频| 亚洲色图在线观看| 亚洲欧洲在线视频| 国产精品久久中文| 国产欧美一区二区| 成人在线激情视频| 国产成+人+综合+亚洲欧洲| 国产精品欧美风情| 国产精品99久久99久久久二8| 国产精品入口日韩视频大尺度| 日韩国产激情在线| 国内偷自视频区视频综合| 成人欧美一区二区三区黑人| 91中文字幕在线| 91在线国产电影| 亚洲97在线观看| 日韩在线一区二区三区免费视频| 欧美成人一区二区三区电影| 在线激情影院一区| xvideos亚洲人网站| 日本中文字幕不卡免费| 国产欧美亚洲视频| 亚洲影院在线看| 国产一区二区欧美日韩| 亚洲a级在线观看| 亚洲国产高潮在线观看| 精品日本美女福利在线观看| 久久久成人精品视频| 91免费欧美精品| 日韩欧美成人精品| 国产成人午夜视频网址| 国产成人福利视频| 国产精品成人在线| 精品国产一区二区三区在线观看| 97超碰蝌蚪网人人做人人爽| 欧美区在线播放| 91欧美精品成人综合在线观看| 中文字幕亚洲自拍| 成人免费xxxxx在线观看| 亚洲人成人99网站| 一区二区欧美久久| 蜜月aⅴ免费一区二区三区| 成人免费淫片视频软件| 国产亚洲精品91在线| 日韩二区三区在线| 91久久夜色精品国产网站| 久久亚洲精品视频| 久久久最新网址| 久久久久久免费精品| 亚洲欧美国产精品va在线观看| 日韩国产欧美精品一区二区三区| 亚洲精品在线不卡| 久久av中文字幕| 国产免费一区二区三区在线能观看| 一本色道久久综合亚洲精品小说| 在线视频欧美日韩| 亚洲码在线观看| 亚洲第一视频网| 中文字幕亚洲欧美| 欧美黑人性猛交| 国产日韩欧美成人| 欧美成人久久久| 国产亚洲精品久久| 国产成人97精品免费看片| 国语自产精品视频在线看| 欧美精品久久久久a| 亚洲最大成人在线| 国产精品美女网站| 91亚洲精品一区| 亚洲欧美日韩天堂| 久久久久久久影视| 国产精品色悠悠| 九九热99久久久国产盗摄| 精品欧美aⅴ在线网站| 亚洲精品自在久久| 色综合五月天导航| 国产精品久久一| 欧美男插女视频| 亚洲欧美在线免费观看| 久久精品亚洲94久久精品| 亚洲二区在线播放视频| 精品国产成人av| 91高清免费视频| 97久久精品人人澡人人爽缅北| 日韩久久精品电影| 中文亚洲视频在线| 欧美一级片久久久久久久| 国产精品海角社区在线观看| 国产成人啪精品视频免费网| 97avcom| 美女视频黄免费的亚洲男人天堂| 成人福利视频网| 亚洲肉体裸体xxxx137| 久久精品99久久香蕉国产色戒| 亚洲图中文字幕| 日韩激情视频在线播放| 日韩av片电影专区| 欧美激情视频一区二区三区不卡| 欧美激情xxxxx| 成人免费午夜电影| 亚洲成人激情在线观看| 精品调教chinesegay| 国产丝袜精品视频| 国产精品扒开腿爽爽爽视频| 88国产精品欧美一区二区三区| 少妇精69xxtheporn| 少妇高潮久久77777| 亚洲精品国产拍免费91在线| 91久久久国产精品| 欧美性xxxxxxxxx| 日韩中文字幕视频在线观看| 91国产视频在线| 亚洲精品一区二区三区婷婷月| 久久精品国产视频| 久久久欧美一区二区| 欧美在线欧美在线| 91探花福利精品国产自产在线| 亚洲最大中文字幕| 色小说视频一区| 久久精品国产久精国产思思| 亚洲自拍欧美色图| 69久久夜色精品国产7777| 国产精品久久久久久久久久久久久久| 亚洲欧洲第一视频| 久久精品视频播放| 亚洲天堂av在线播放| 久久久电影免费观看完整版| 午夜精品久久久久久久久久久久久| 中文字幕在线国产精品| 成人网在线免费观看| 一区二区三区天堂av| 亚洲人成网7777777国产| 日韩国产高清视频在线| 国产精品偷伦免费视频观看的| 色妞一区二区三区| 日本午夜人人精品| 美女国内精品自产拍在线播放| 日韩精品丝袜在线| 欧美人与性动交a欧美精品| 亚洲欧美国产va在线影院| 日韩欧美一区二区三区| 欧洲s码亚洲m码精品一区| 国产精品视频久久久| 亚洲欧美一区二区激情| 国产欧美精品在线播放| 久久视频国产精品免费视频在线| 在线观看久久av| 最近2019年中文视频免费在线观看| 日韩在线精品视频| 国产亚洲美女精品久久久| 日韩欧中文字幕| 国产中文日韩欧美| 另类天堂视频在线观看| 欧美成人免费在线视频| 成人乱人伦精品视频在线观看| 亚洲wwwav| 国产成人在线一区二区| 91国产美女在线观看| 欧美亚洲国产视频| 日韩欧美在线一区| 国产精品精品久久久久久| 伊人久久五月天| 国色天香2019中文字幕在线观看| 久久久日本电影|