本文介紹vector和list的用法、適合的場(chǎng)景以及在無(wú)法估算實(shí)際業(yè)務(wù)場(chǎng)景中vector和list的代價(jià)情況下如何使用vector和list.
1 用法
vector和list是C++標(biāo)準(zhǔn)庫(kù)提供的兩種容器。其實(shí),這兩種容器與我們學(xué)過的數(shù)據(jù)結(jié)構(gòu)中的數(shù)組和鏈表是一樣的。只不過,標(biāo)準(zhǔn)庫(kù)將其實(shí)現(xiàn)成模板讓其更加的通用。下面簡(jiǎn)要介紹下C++11新增的幾種方法。其他內(nèi)容見張老師的課件。
1.1 構(gòu)造函數(shù)
C++11支持列表初始化,因此在容器的構(gòu)造函數(shù)中新增了帶列表初始化的構(gòu)造函數(shù)。函數(shù)聲明如下:
C c{a, b, c}
有了這個(gè)構(gòu)造函數(shù),我們就可以使用如下的方式構(gòu)造vector/list:
vector<int> ivec{1, 2, 3, 4, 5};
list<int> ilst{5, 6, 7, 8, 9};
在C++11以前,我們要使用下面的方式來達(dá)到相同的目的:
vector<int> oivec;
for (int i = 0;i < 5;i++)
oivec.push_back(i);
//或者
int intArray[] = {1, 2, 3, 4, 5};
vector<int> oivec1(intArray, intArray + 5);
1.2 賦值
得益于列表初始化,復(fù)制也支持列表的賦值。聲明為c1 = {e1, e2, e2}。用法與構(gòu)造函數(shù)類似。
1.3 添加/刪除
插入/刪除新增的接口如下:
c.emplace(inits) //使用inits中的元素構(gòu)造一個(gè)c元素的對(duì)象,并插入到c中
c.emplace_back(inits)
c.emplace_front(inits)
一般的,我們插入元素會(huì)使用c.insert(args)。其中args是c中元素的對(duì)象。當(dāng)調(diào)用insert的成員函數(shù)時(shí),我們將元素類型的對(duì)象傳遞給容器,這些容器被拷貝到容器中。當(dāng)我們使用emplace時(shí),我們將參數(shù)傳遞給元素的構(gòu)造函數(shù)。emplace直接使用這些元素構(gòu)造對(duì)象并保存在容器中。使用示例如下:
vector<complex<int> > cvec; /*定義一個(gè)存儲(chǔ)complex對(duì)象的數(shù)組*/
complex<int> c(1, 2);
cvec.insert(cvec.begin(), c); /*C++11之前使用的調(diào)用方式*/
cvec.emplace(cvec.begin(), 2, 3); /*c++11新增的調(diào)用方式,直接傳元素的參數(shù)給emplace,emplace在調(diào)用complex來構(gòu)造對(duì)象*/
2 適合場(chǎng)景
本節(jié)介紹vector&list的使用場(chǎng)景。一般vector會(huì)實(shí)現(xiàn)成數(shù)組的方式,即分配一段連續(xù)的內(nèi)存空間在存放數(shù)組元素,而list會(huì)實(shí)現(xiàn)成雙向鏈表,便于雙向訪問。因此,vector和list也分別具有數(shù)組和鏈表的優(yōu)缺點(diǎn)。
vector的優(yōu)缺點(diǎn):
1.優(yōu)點(diǎn)
-提供高效、靈活的內(nèi)存管理;
-支持隨機(jī)訪問,訪問速度非???br>
2.缺點(diǎn)
+在數(shù)組中間插入元素需要移動(dòng)后續(xù)的元素,因此插入數(shù)組很慢
+插入數(shù)據(jù)時(shí)可能伴隨大量?jī)?nèi)存分配
list的優(yōu)缺點(diǎn):
1.優(yōu)點(diǎn)
+list一般實(shí)現(xiàn)為鏈表,節(jié)點(diǎn)與節(jié)點(diǎn)之間是通過指針鏈接的,因此在list中插入/刪除元素很快,只需要常量的時(shí)間。
2.缺點(diǎn)
+不支持隨機(jī)訪問,訪問list內(nèi)元素的速度與list的元素?cái)?shù)量正相關(guān)。
從上面的介紹中,不難發(fā)現(xiàn)vector和list各自適合的場(chǎng)景。如果我們的業(yè)務(wù)中需要快速、隨機(jī)的訪問容器中的元素并且對(duì)向數(shù)組中插入數(shù)據(jù)的需求不高的話,那vector是很好的選擇;如果業(yè)務(wù)對(duì)快速插入的需求高,對(duì)隨機(jī)訪問元素的要求低的話,那就可以選擇list。當(dāng)然,除此之外,還有些基本的原則:
1.通常建議使用vector,除非有很好的理由。
2.如果程序元素小且多,空間的額外開銷很重要的話,不要使用list。
3 業(yè)務(wù)場(chǎng)景不明晰是如何使用vector和list
在實(shí)際開發(fā)過程中,可能無(wú)法正確評(píng)估vector/list對(duì)系統(tǒng)性能的影響,但是有需要vector和list的一些公有操作,如果插入,查詢等。這時(shí)候可以定義一個(gè)適配器ListAdpter,該適配器組合vecotr/list并定義一套vector/list的公有接口。然后,我們的程序通過調(diào)用ListAdpter中的操作,進(jìn)而對(duì)程序屏蔽底層的實(shí)現(xiàn)。然后,在對(duì)系統(tǒng)進(jìn)行壓力測(cè)試,評(píng)估出vector/list對(duì)系統(tǒng)的影響,而且抉擇出啟用哪種容器。
4 參考
1.cpp primer 5th edition