999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于容器對象的動態控件數組研究

2012-04-12 00:00:00劉艮等
現代電子技術 2012年1期

摘 要:動態控件數組是應用程序設計中經常用到的重要手段之一。合理地使用動態控件數組不但能簡化程序、方便維護,還可以節約內存空間,對動態控件數組的研究有助于增加應用程序靈活性,能有效提高編程效率。鑒于此,提出了在C++Builder環境下基于容器對象的動態控件數組實現方案,分別給出利用三種容器對象TList,DynamicArray和Vector實現動態控件數組的思想,對三者的性能進行比較分析,并總結了實現動態控件數組的原理、方法和技巧。

關鍵詞:動態控件數組; 容器; TList; DynamicArray; Vector

中圖分類號:TN911.7-34; TP311.11

文獻標識碼:A

文章編號:1004-373X(2012)01-0146-04

Research on dynamic control arrays based on container object

LIU Gen, YANG Yu-qin, JIANG Tian-fa

(College of Computer Science, South-central University for Nationalities, Wuhan 430073, China)

Abstract:

Dynamic control arrays are often used in application programming. Reasonably using dynamic control arrays can simplify application procedures and their maintenance, save memory space, increase the flexibility of application procedure, and effectively improve the efficiency of application programming. The schemes of dynamic control arrays based on container object under C++Builder are presented. Three kinds of container objects TList, DynamicArray and Vector are used to realize dynamic control arrays, whose performance are analyzed and compared. The principle, methods and technique of dynamic control arrays are summarized.

Keywords: dynamic component arrays; container; TList; DynamicArray; Vector

收稿日期:2011-08-11

基金項目:國家自然科學基金項目(40571128);湖北省教育廳科研項目(B20110804)

0 引 言

動態數組[1]可以在運行期間改變數組大小,具有很強的靈活性,為開發者帶來極大便利,廣泛應用于各個領域[2-3]。動態控件數組就是一種特殊的動態數組,它的元素類型是控件類型。控件數組應該包含以下三個要素:

(1) 允許多個控件共享同一個事件句柄。即動態生成的多個同類型控件可以使用相同的事件名。這一點是BCB已經具備的功能。

(2) 可以在運行期間添加或者刪除控件。BCB已經提供了這種機制。

(3) 可以方便地將多個控件組合為控件數組進行管理和使用。要組合控件最好的方法就是使用容器。BCB中能夠實現控件數組的容器可以分為三種:第一種是VCL(Visual Componet Library,可視化組件庫)中的TList類;第二種是VCL中的DynamicArray類;第三種是STL[4](Standard Template Library,標準模板庫)中的Vector容器類。

文獻[5]提出一種基于TList類的控件數組實現方法,在其基礎上本文提出基于容器類的動態控件數組實現方案,并詳細分析了其性能效率。

1 基于TList類的控件數組

1.1 VCL中的TList類

TList是VCL提供的一個用于維護對象列表的類,它是以鏈式存儲指針的方式實現的。它存儲了用于維護各種類指針的索引,這些索引存有指向各種對象的指針。為方便在對象列表中添加、刪除、查找、訪問、排序或者重組對象,TList提供了方便全面的鏈表功能,包括Capacity,Count,Items等主要屬性和Add,Insert,Delete,Clear,First,Last等主要方法,各屬性和方法詳細信息如表1所示。

1.2 基于TList類的控件數組的實現思想

文獻[5]提出一種基于TList類的控件數組實現方案,下面簡要闡述其基本思想。

定義TList類型指針對象,建立控件數組CList,并調用構造函數對其進行初始化:

TList *CList = new TList() ;

動態生成控件對象Button,添加到CList中:

TButton *Button=new TButton(this) ;

CList->Add(Button) ;

表1 TList類的主要屬性和方法

名稱相關信息

Capacity標識TList對象維護的指針數組大小

Count標識Items數組中項的數量

Items可以獲得數組中指定對象的指針

Add在列表的末尾插入新項

Clear刪除列表中所有項

Delete刪除列表中指定位置的項

First返回Items數組中第一個指針

Insert向Items數組中指定位置插入新的項

Last返回Items數組中最后一個指針

為Button聲明并自定義事件MBClick,讓所有動態生成的控件共享事件句柄:

void __fastcall TForm1::MBClick(

TObject *Sender) ;

Button->OnClick=MBClick ;

通過TList對象的Items屬性訪問CList中的對象,甚至可以在自定義事件中訪問TList對象中動態生成的控件:

void __fastcall TForm1::MBClick(TObject

*Sender)

{

ShowMessage(((TButton*)(CList->Items[CList->Count-1]))->Caption;

}

刪除CList中指定成員對象(第i個)時,先將CList中該成員對象的類指針索引裝入臨時指針,然后刪除臨時指針所指對象,同時刪除控件數組中的指針記錄:

TButton *temp = (TButton *)CList->Items[i] ;

delete temp ;

CList->Delete(i) ;

清空整個CList時,先刪除其中所有成員對象,再用Clear方法清空。程序結束時CList需要銷毀,可在窗體的析構函數中加入以下代碼:

delete CList;

2 基于DynamicArray模板的控件數組

2.1 VCL中的DynamicArray模板類

DynamicArray是VCL提供的一個用于實現變長動態數組的模板類[6],使用二進制數據塊兼容Object Pascal動態數組實現。DynamicArray也可以看作是一個可以存放各種控件對象的容器,只需將動態數組聲明中的數據類型設置為相應控件類型即可。為方便管理動態數組,DynamicArray模板提供了Length,High,Low等屬性和Copy,CopyRange等方法,并重載了賦值運算符“=”、比較運算符“==”和訪問數組元素的“[]”運算符,如表2所示。

表2 DynamicArray類的主要屬性、方法和操作符

名稱相關信息

屬性

Length動態數組長度

High動態數組的下標上界Length-1

Low動態數組的下標下界零

方法

Copy將數組內容復制到指定數組中

CopyRange復制一段連續元素到指定數組中

操作符

“=”引用型賦值操作符

“==”判斷動態數組指針是否相同

“[]”用于訪問動態數組中的元素

2.2 基于DynamicArray模板的控件數組實現思想

利用DynamicArray模板實現動態控件數組時,需要將動態數組的類型設置為某一控件類型,通過在程序中動態修改動態數組的Length屬性來實現數組大小的動態變化。下面以動態按鈕數組(BArray)為例,詳細說明動態控件數組實現思想。

聲明動態按鈕數組:

DynamicArray BArray ;

動態地向BArray中添加成員對象時,先將BArray的Length屬性增加1,以便為待添加的新對象預留空間:

BArray.Length = BArray.Length + 1 ;

創建待添加的控件對象并裝入新開辟的空間:

BArray[BArray.High] = (new TButton(this)) ;

獲取新添加的控件對象:

TButton* Button = BArray[BArray.High] ;

刪除指定成員(比如第i個)對象時,先刪除動態數組中第i個成員對象:

delete BArray[i] ;

然后使用循環語句將被刪除成員對象后面的元素全部前移:

for(int k = i ; k < BArray.High ; k++)

{

BArray[i] = BArray[i+1] ;

}

最后將BArray的Length屬性減少1:

BArray.Length = BArray.Length - 1 ;

如果要清空動態數組BArray中的所有成員,先要使用循環語句逐一刪除BArray中的所有元素:

for(int k = 0 ; k

{

delete BArray[k] ;

}

然后將動態數組BArray的Length屬性設置為0,但無需使用delete語句銷毀BArray:

BArray.Length = 0 ;

3 基于Vector容器類的控件數組

3.1 STL中的Vector容器類

Vector是STL容器類中最簡單的容器類,通常也是效率最高的容器類。Vector[7]是一個隨機存取的Sequence容器,采用連續的內存空間存放數據。它支持常數時間的尾部插入和刪除、線性時間的其他位置的插入和刪除。Vector模板類class vector接口成員(public)如表3所示。

表3 Vector接口類中包含的主要內容

類型定義value_type,allocator_type,reference,

iterator,size_type,difference_type;

構造函數vector (size_type, const T, const 

Allocator = Allocator());

拷貝構造函數vector (const vector);

析構函數~vector ();

迭代器begin ();end ();

關于容量大小的函數size();max_size();resize(size_type, T);capacity () ;empty () ;reserve (size_type);

用于訪問的操作和函數operator[] (size_type);at (size_type);front();back();

更改容器內容的函數push_back (const T);pop_back ();void insert (iterator, size_type, const T);erase (iterator);swap (vector);clear();

3.2 基于Vector容器類的控件數組的實現思想

基于Vector容器實現動態控件數組的思想[8],將Vector中元素類型設置為相應的控件類型,然后利用Vector提供的push_back或insert方法,將動態生成的控件對象裝入容器中,利用Vector提供的訪問容器中元素的方法訪問成員對象,或者利用Vector提供的pop_back或erase方法刪除容器中的元素。下面還是以動態按鈕數組(BVec)為例,詳細說明基于Vector的動態控件數組實現過程。

定義相應類型(比如TButton)的Vector容器:

vector BVec ;

創建Button控件對象,然后添加到容器中:

BVec.push_back(new TButton(this)) ;

獲取剛加入的控件對象指針,方便后續訪問:

TButton* Button = *(BVec.end() - 1) ;

在刪除容器中指定的元素(比如第i個元素)時,先要刪除容器中該成員對象的類指針所指的對象,然后清除容器中該成員對象的值:

TButton* tempButton= *(BVec.begin() + i);

delete tempButton ;

BVec.erase(BVec.begin() + i) ;

清空容器時先刪除容器中所有成員的類指針所指的對象,這一點可以通過定義一個迭代器并遍歷容器所有元素來實現。然后再清除容器中所有元素的值:

vector :: iterator it ;

for(it = BVec.begin() ; it != BVec.end() ; it++)

delete *it ;

BVec.erase(BVec.begin(),BVec.end()) ;

4 基于容器對象的動態控件數組性能分析

4.1 基于TList類的控件數組性能分析

基于TList類的控件數組應用廣泛[9-10],實現方法簡單,添加或刪除對象方便而高效。但是這種方法存在以下4個方面的缺陷。

安全性問題 TList類本身就是一個缺乏類型安全支持的類。從其Add方法原型int_fastcall Add(void * Item)可以看出,TList對象存儲并維護的是void*空指針。但是BCB編譯器會將Add函數接收到的任何類型的指針轉換為void*類型,而不做任何類型檢查。同時,在引用控件數組中的一個對象時,需要將一個void*類型的指針強制轉換為相應控件類型的指針。如果控件數組包含多種類型的成員控件,這時就無法確定空指針該強制轉換為哪種類型的指針。一旦類型轉換錯誤,那么在訪問成員控件時就會產生嚴重的問題。

內存空間釋放問題 一方面,TList不能自動刪除列表中的指針;另一方面,由于列表中的指針是空指針,刪除空指針的時候不會調用析構器中的析構函數,那么就無法釋放內存空間,從而造成內存泄露。

效率問題 實驗表明,當TList存儲5 000個以上對象時,效率就會大幅下降。

移植性問題 由于BCB的VCL完全是用Object Pascal語言編的,使得BCB同時獲得了Pascal和C++的強大功能,同時可移植性就很差。

4.2 基于DynamicArray類的控件數組性能分析

用DynamicArray實現控件數組,原理簡單、代碼簡潔,不存在類型安全和內存釋放問題。但是,DynamicArray使用二進制數據塊兼容Object Pascal動態數組實現,這會帶來系統瓶頸,嚴重影響運行效率。DynamicArray的空間擴充機制也不盡完美。當數組長度超過固定大小時,就會頻繁地重新申請內存空間,并將原來內存空間中的二進制數據塊拷貝到新申請的內存空間中,然后將原空間釋放掉,這就會大大降低運行效率。特別是如果二進制數據塊比較大的時候,系統瓶頸尤其突出。另外,由于DynamicArray是VCL中的模板類,故移植性較差。

4.3 基于Vector容器類的控件數組性能分析

Vector采用線性連續的內存空間存放數據,因而隨機訪問數組元素和Vector尾部插入元素效率很高,但是在任意位置插入元素的效率比較低。為了提高效率,Vector使用了自增長機制,實際上就是運用動態彈性內存空間[8],隨著新元素的加入,自行擴充內存空間。為了合理控制空間大小、提高重新配置空間時的效率,Vector 實際配置的空間比需求空間大一些,以備將來可能的擴充。向Vector中插入元素時,首先考慮備用空間是否足夠,如果夠就插入到備用空間,否則,重新配置雙倍于現在容量的內存空間,然后將原來的數據拷貝到新空間中,最后釋放原內存空間。在控件數組中元素個數不超過1 000萬個時,Vector的空間擴充方式效率都是很高的。Vector的空間擴充過程如圖1所示。

圖1 Vector內存空間擴展示意圖

另外,當容器內元素操作比較復雜時,Vector效率不佳。

5 結 語

BCB是一個優秀的應用程序開發平臺,其提供的VCL庫更是為開發者帶來了極大便利。VCL提供的TList和DynamicArray都可以很容易地實現動態控件數組。但是,TList缺乏類型安全支持,而且Dynamic-Array也存在系統瓶頸問題,而且移植性都比較差,因此它們適合于小規模的局部應用的動態控件數組中。而標準模板庫STL提供的容器類Vector具有完備的類型安全機制,移植性比較好,執行效率也相對很高,但是在支持數組元素復雜操作方面欠佳,故這種方法適合于較大規模的通用動態控件數組中??傊?,沒有哪種方法一定是最好的,具體采用什么方法要根據問題規模、應用范圍等因素來決定。

參 考 文 獻

[1]陳鳳祥,李汪根.C++動態數組的實現與重用[J].計算機技術與發展,2010,20(2):79-82.

[2]孫桂娟,張慶明,鄭全平,等.基于可變數組管理方法的震塌破壞數值仿真[J].北京理工大學學報,2009,29(6):492-496.

[3]喬平安.動態統計圖控件的設計與實現[J].現代電子技術,2006,29(6):118-120.

[4]葛建芳.C++標準模板庫與代碼重用[J].南通大學學報:自然科學版,2006,5(2):71-74.

[5]許天然.在C++Builder中實現控件數組[J].瓊州大學學報,2006,13(5):27-29.

[6]周熙,汪紅.C++Builder環境下MVC框架結構的應用[J].中南民族大學學報:自然科學版,2007,26(2):87-89.

[7]宮護震,史云鵬,孫吉赟.一種基于STL(標準模板庫)的三維數據可視化容器設計[J].現代電子技術,2007,30(22):80-81.

[8]帖軍,王小榮,金佳.移動實時環境下的數據一致性研究[J].中南民族大學學報:自然科學版,2011,30(2):92-95..

[9]景春國,舒冬梅.TList對象在監控軟件數據點的內存管理和處理方面的應用[J].現代電子技術,2003,26(2):7-12.

[10]李繼良.用TList類構建粗糙集分類系統[J].計算機與現代化,2002(4):17-19.

作者簡介:

劉 艮 男,1987年出生,山西大同人,碩士研究生。主要研究方向為信息安全與分布式系統開發。

楊玉琴 女,1987年出生,湖北武漢人,碩士研究生。主要研究方向為分布式系統開發與數字水印。

蔣天發 男,1954年出生,湖北荊門人,教授,研究生導師。主要研究方向為網絡安全和空間數據組織與管理。

主站蜘蛛池模板: 精品视频一区二区观看| 亚洲精品视频免费看| 日韩欧美一区在线观看| 玖玖免费视频在线观看| 夜夜高潮夜夜爽国产伦精品| 国产制服丝袜无码视频| 色天天综合| 中文字幕永久在线看| 91青青草视频| 亚洲自偷自拍另类小说| 国产精品三级专区| 欧美激情第一欧美在线| 视频二区欧美| 99在线观看免费视频| 国产91在线|中文| 国产91成人| 无码福利视频| 久久国产高清视频| 伊人久久婷婷| 日本亚洲国产一区二区三区| 欧美特黄一免在线观看| 91偷拍一区| 成人一级黄色毛片| 色综合网址| 又爽又大又黄a级毛片在线视频| 国产精品无码一二三视频| 99热线精品大全在线观看| 999在线免费视频| 日本一本正道综合久久dvd| 国产精品女主播| 色135综合网| 成人福利在线视频| 成人无码区免费视频网站蜜臀| 亚洲无码91视频| 国产精品亚洲五月天高清| 国产91小视频在线观看| 亚洲欧美成人综合| 欧美日韩北条麻妃一区二区| 99久久精品视香蕉蕉| 亚洲精品成人福利在线电影| 国产日韩欧美在线播放| 一级一级一片免费| 中国精品久久| 国产一级二级在线观看| 久久成人免费| 国产91九色在线播放| 成人精品午夜福利在线播放 | 久久夜色精品国产嚕嚕亚洲av| 免费无码又爽又黄又刺激网站| 热久久综合这里只有精品电影| 中文无码影院| 国产亚洲美日韩AV中文字幕无码成人 | 最新加勒比隔壁人妻| 91青青在线视频| 亚洲精品制服丝袜二区| 日韩欧美中文在线| 欧美激情福利| 青青操国产| 精品视频在线一区| 超薄丝袜足j国产在线视频| AV不卡在线永久免费观看| 波多野结衣亚洲一区| 午夜激情婷婷| 一区二区理伦视频| 国内精品伊人久久久久7777人 | 国产精品成人一区二区| 日韩福利在线视频| 午夜激情福利视频| 久久国产精品波多野结衣| 国产欧美自拍视频| 伊人久久久久久久久久| 色婷婷在线影院| 亚洲精品高清视频| 国产美女在线观看| 午夜视频在线观看区二区| 亚洲欧美日韩天堂| 毛片在线播放a| 国产特级毛片| 国产男女XX00免费观看| 亚洲AV成人一区国产精品| 国产靠逼视频| 国产91视频观看|