CAVector、CAList、CADeque、CAMap(數(shù)據(jù)容器)

2018-08-27 15:29 更新
CAVector、CAList、CADeque、CAMap 對(duì)應(yīng)C++中的STL提供的vector、list、deque、map使用方式一致,但是CAVector、CAList、CADeque、CAMap添加和移除元素時(shí),遵循CrossApp的內(nèi)存管理原則,分別在添加元素的時(shí)候Object的引用計(jì)數(shù)+1,移除的時(shí)候Object的引用計(jì)數(shù)-1.


我們看看C++中他們的描述與不同。
c++標(biāo)準(zhǔn)庫(kù)中,容器vector和list都可以用來存放一組類型相同的數(shù)據(jù)。而且二者不同于數(shù)組的一點(diǎn)是,支持動(dòng)態(tài)增長(zhǎng)。但它們還是有有幾點(diǎn)不同

(1)  vector是順序表,表示的是一塊連續(xù)的內(nèi)存,元素被順序存儲(chǔ);list是雙向連接表,在內(nèi)存中不一定連續(xù)。

(2)當(dāng)數(shù)值內(nèi)存不夠時(shí),vector會(huì)重新申請(qǐng)一塊足夠大的連續(xù)內(nèi)存,把原來的數(shù)據(jù)拷貝到新的內(nèi)存里面;list因?yàn)椴挥每紤]內(nèi)存的連續(xù),因此新增開銷比vector小。

(3)list只能通過指針訪問元素,隨機(jī)訪問元素的效率特別低,在需要頻繁隨機(jī)存取元素時(shí),使用vector更加合適。

(4)當(dāng)向vector插入或者刪除一個(gè)元素時(shí),需要復(fù)制移動(dòng)待插入元素右邊的所有元素;因此在有頻繁插入刪除操作時(shí),使用list更加合適。

我再來看看對(duì)deque對(duì)描述

  deque是雙向開口的連續(xù)性存儲(chǔ)空間。雖說是連續(xù)性存儲(chǔ)空間,但這種連續(xù)性只是表面上的,實(shí)際上它的內(nèi)存是動(dòng)態(tài)分配的,它在堆上分配了一塊一塊的動(dòng)態(tài)儲(chǔ)存區(qū),每一塊動(dòng)態(tài)存儲(chǔ)去本身是連續(xù)的,deque自身的機(jī)制把這一塊一塊的存儲(chǔ)區(qū)虛擬地連在一起。

    它首次插入一個(gè)元素,默認(rèn)會(huì)動(dòng)態(tài)分配512字節(jié)空間,當(dāng)這512字節(jié)空間用完后,它會(huì)再動(dòng)態(tài)分配自己另外的512字節(jié)空間,然后虛擬地連在一起。deque的這種設(shè)計(jì)使得它具有比vector復(fù)雜得多的架構(gòu)、算法和迭代器設(shè)計(jì)。它的性能損失比之vector,是幾個(gè)數(shù)量級(jí)的差別。所以說,deque要慎用。

C++中map容器提供一個(gè)鍵值對(duì)容器,map只允許一個(gè)鍵對(duì)一個(gè)值。

CrossApp設(shè)計(jì)它們時(shí)也遵循類似的設(shè)計(jì)原則,所以我們使用起來也是類似的用法。

我們對(duì)數(shù)據(jù)容器的操作一般為:增、刪、查、遍歷

我們這里分別對(duì)CAVector、CAList、CADeque、CAMap的常用函數(shù)進(jìn)行說明:

CAVector<CAObject*> ca_vector;
//增
ca_vector.insert(size_t index, CrossApp::CAObject *object);//插入一個(gè)元素到指定位置
ca_vector.pushBack(CrossApp::CAObject *object);//在list末尾插入一個(gè)元素
    
//刪
ca_vector.erase(ca_vector.begin());//刪除指定位置的元素
ca_vector.erase(ca_vector.begin(),ca_vector.end());//刪除指定范圍的元素
ca_vector.popBack();//刪除最后一個(gè)元素
ca_vector.clear();//刪除所有元素
     
//查
ca_vector.empty();//是否含有元素
ca_vector.size();//返回vector中的元素個(gè)數(shù)
ca_vector.end();//返回末尾的迭代器
ca_vector.begin();//返回指向第一個(gè)元素的迭代器
ca_vector.front();//返回第一個(gè)元素
ca_vector.back();//返回最后一個(gè)元素
  
//遍歷
for (int i = 0; i < ca_vector.size(); i++) {
    CAObject* obj = ca_vector.at(i);
}
CAList<CAObject*> ca_list;
//增
ca_list.insert(size_t index, CrossApp::CAObject *object);//插入一個(gè)元素到指定位置
ca_list.pushBack(CrossApp::CAObject *object);//在list末尾插入一個(gè)元素
ca_list.pushFront(CrossApp::CAObject *object);//在list頭部添加一個(gè)元素
//刪
ca_list.erase(ca_list.begin());//刪除指定位置的元素
ca_list.erase(ca_list.begin(),ca_list.end());//刪除指定范圍的元素
ca_list.popBack();//刪除最后一個(gè)元素
ca_list.popFront();//刪除第一個(gè)元素
ca_list.clear();//刪除所有元素
//查
ca_list.size();//返回list中的元素個(gè)數(shù)
ca_list.begin();//返回指向第一個(gè)元素的迭代器
ca_list.end();//返回末尾的迭代器
ca_list.front();//返回第一個(gè)元素
ca_list.back();//返回最后一個(gè)元素
//遍歷
std::list<CAObject*>::iterator it;
for (it = ca_list.begin(); it != ca_list.end(); it++) {
    CAObject* obj = (CAObject*)*it;
}
CADeque<CAObject*> ca_deque;
//增
ca_deque.insert(size_t index, CrossApp::CAObject *object);//插入一個(gè)元素到指定位置
ca_deque.pushBack(CrossApp::CAObject *object);//在list末尾插入一個(gè)元素
ca_deque.pushFront(CrossApp::CAObject *object);//在list頭部添加一個(gè)元素
     
//刪
ca_deque.erase(size_t index);//刪除指定位置的元素
ca_deque.erase(ca_deque.begin()+1, ca_deque.end()-2);//刪除指定范圍的元素
ca_deque.popBack();//刪除最后一個(gè)元素
ca_deque.popFront();//刪除第一個(gè)元素
ca_deque.clear();//刪除所有元素
    
//查
ca_deque.size();//返回deque中的元素個(gè)數(shù)
ca_deque.begin();//返回指向第一個(gè)元素的迭代器
ca_deque.end();//返回末尾的迭代器
ca_deque.front();//返回第一個(gè)元素
ca_deque.back();//返回最后一個(gè)元素
ca_deque.at(size_t index);//返指定位置的元素
     
//遍歷
for (int i = 0; i < ca_deque.size(); i++) {
    CAObject* obj = ca_deque.at(i);
}
CAMap<int, CAObject*> ca_map;
//增
ca_map.insert(int key, CrossApp::CAObject *object);//增加一個(gè)元素鍵值對(duì)
     
//刪
ca_map.erase(int key);//通過key刪除元素
ca_map.clear();//刪除所有元素
   
//查
ca_map.empty();//判斷mpa是否是空
ca_map.contains(int key);//是否有這個(gè)key返回bool
ca_map.getValue(int key);//根據(jù)key返回對(duì)應(yīng)的Value
std::vector<int> vec = ca_map.getKeys();//返回包含所有key的vector
     
//遍歷
std::map<int, CAObject*>::iterator it;
for (it = ca_map.begin(); it != ca_map.end(); ++it) {
    int key = it->first;
    CAObject* obj = it->second;
}
我們以CAVector為例子做一個(gè)內(nèi)存管理的實(shí)驗(yàn),看在添加和移除元素時(shí),CAObject的引用計(jì)數(shù)是否發(fā)生了變化。
CAObject* obj = new CAObject();
     
CAVector<CAObject*> ca_vector;
     
//打印引用計(jì)數(shù)
CCLog("count:%d",obj->retainCount());
     
//把obj添加到vector尾部
ca_vector.pushBack(obj);
     
//打印引用計(jì)數(shù)
CCLog("count:%d",obj->retainCount());
     
//把obj移除
ca_vector.eraseObject(obj);
     
//打印引用計(jì)數(shù)
CCLog("count:%d",obj->retainCount());

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)