五、STL容器共性機制(解釋二的疑問)、STL容器使用時機

1.STL容器共性機制

STL容器所提供的都是值(value)寓意,而非引用(reference)寓意,也就是說當我們給容器中插入元素的時候,容器內(nèi)部實施了拷貝操作,將我們要插入的元素再另行拷貝一份放入容器中,而不是將數(shù)據(jù)元素直接放進容器中,也就是說我們所提供的元素必須能夠被拷貝

  • 除了queue和stack之外,每個容器都提供可返回迭代器的函數(shù),運用返回的迭代器就可以訪問元素
  • 通常STL不會拋出異常,需要使用者傳入正確參數(shù)
  • 每個容器都提供了一個默認的構造函數(shù)和默認的拷貝構造函數(shù)
  • 大小相關的構造方法:1 size()返回容器中元素的個數(shù) 2 empty()判斷容器是否為空
#include <iostream>
#include <vector>

using namespace std;

class Teacher{
public:
    Teacher(char *name,int age){
       int len = strlen(name) + 1;
       this->name = new char[len];//在堆分配內(nèi)存
       strcpy(this->name,name);

       this->age = age;
    }

    //拷貝構造
    Teacher(const Teacher &t){
        int len = strlen(t.name) + 1;
        this->name = new char[len];
        strcpy(this->name,t.name);

        this->age = agel
    }

    //重載=
    Teacher& operator=(Teacher &t){
        int len = strlen(t.name) + 1;
        if (this->name != NULL)
        {
            delete[] this->name;
        }
        this->name = new char[len];
        strcpy(this->name,t.name);

        this->age = agel

        return *this;
    }

    ~Teacher(){
        if (this->name != NULL)
        {
            delete[] this->name;
        }
        this->age = 0;
    }

    char *name;
    int age;
}


//測試函數(shù) 深拷貝和淺拷貝
void test01(){  
 //會崩潰?。≡蚓褪侵赶騛aaa的有兩個指針,卻只釋放一個,下圖有解
 //歸根結底是沒有寫深拷貝的拷貝構造函數(shù)或重載=運算符
   Teacher t1("aaaa",19);
   vector<Teacher> v;
   v.push_back(t1);

}


int main(){

   cout<<"hello world..."<<endl;

   return 0;

}
1.png

奔潰的原因是由于我們沒有提供拷貝構造函數(shù),沒有重構=操作符,vector對我們的mc對象進行了簡單的淺拷貝,將拷貝的對象插入到容器中,導致我們的mc對象的data指針和容器中mc對象的拷貝對象中的data指針都指向了我們在堆內(nèi)存分配的內(nèi)存,當函數(shù)結束,兩個對象都調(diào)用了析構函數(shù),先調(diào)用析構函數(shù)的對象成功釋放了堆區(qū)內(nèi)存,后調(diào)用析構函數(shù)的對象一釋放,程序就掛掉了。
原因在于兩個指針指向了同一塊堆區(qū)內(nèi)存,這樣會導致不可預知的結果,函數(shù)結束其中一個調(diào)用析構函數(shù),銷毀data指向的內(nèi)存空間,而另一個對象析構的時候回掛掉
問題的解決辦法就是,給我們的對象提供一個拷貝構造函數(shù),并且重構=操作符,兩個指針分別指向自己的那一塊內(nèi)存,互不影響。

2.png

2.STL容器使用時機

- vector deque list set multiset map multimap
典型內(nèi)存結構 單端數(shù)組 雙端數(shù)組 雙向鏈表 二叉樹 二叉樹 二叉樹 二叉樹
可隨機存取 對key而言:是
元素搜尋速度 非常慢 對Key而言:快 對key而言:快
元素安插移除 尾端 頭尾兩端 任何位置 - - - -
  • vector的使用場景:比如軟件歷史操作記錄的記錄,我們經(jīng)常查看歷史記錄,比如上一次記錄,上上次記錄,但卻不會去刪除記錄,因為記錄是事實的描述。
  • deque的使用場景:比如派對購票系統(tǒng),對排隊著的存儲可以采用deque,支持頭端快速移除,尾端的快速添加。如果采用vector,則頭端移除時,會移動大量數(shù)據(jù),速度慢。

vector與deque的比較

  1. vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的開始位置卻是不固定的。
  2. 如果有大量釋放操作的話,vector花的時間更少,這跟二者的內(nèi)部實現(xiàn)有關
  3. deque支持頭部的快速插入和快速移除,這是deque的優(yōu)點
  • list的使用場景:比如公交車乘客的存儲,隨時可能有乘客下車,支持頻繁的不確定位置元素的移除插入
  • set的使用場景:比如對手機游戲的個人得分記錄的存儲,存儲要求從高分到低分的順序排序
  • map的使用場景:比如按ID號存儲十萬個用戶,想要快速要通過ID查找對應的用戶。二叉樹的查找效率,這時就體現(xiàn)出來了。如果是vector容器,最壞情況下可能要遍歷整個容器才能找到該用戶
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容