C++ 標準模板庫組件介紹

jopen 12年前發布 | 2K 次閱讀

在前幾天的阿里面試過程中,問到了我標準模板庫的繼承體系。平時開發對vector,list, map,set ,stack等容器用的比較多,但是沒有深入研究過。經歷過面試,發現了很多需要完善和提高的地方。
但是有個問題哦,標準模板庫中得幾大組件沒有啥繼承關系,只是說有某些容器之間有適配關系。

Container(容器):

所謂容器,就是存放數據的倉庫,定義了數據在內存中的組織方式,
主要:有序列式容器(線性數據結構)、關聯連式容器(非線性數據結構:樹結構)
序列容器,典型的容器vector,相對于C++內嵌的數組,vector的優點是支持數據的動態擴展。
而空間的動態擴展,有空間配置器配置。它會為容器提供空間分配的策略,比如空間不夠時增長的幅度。

 關聯式容器:關聯式容器的思想類似于關系數據庫,由key-value組成。 主要分為map和set,hash及其相關衍生.

 

Iteraotrs(迭代器):

迭代器統一了容器的訪問操作,很好的東西。想到了迭代器模式
Container<Type> cons;
for (Container<Type>::iterator iter = cons.begin(); 
     iter != cons.end(); iter++)
{
    visit(iter);
}

看看《STL源碼分析》中關于vector的定義
template<class T, class Alloc = alloc>
class vector
{
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type* iterator;
    ......
}

這里很明顯的是通過宏定義將指針定義為vector的迭代器,提供統一訪問,但是本質上還是指針哈。

VC的vector的迭代器定義:是一個類哈,有許多數據組成了迭代器的定義,其中有指針,有引用。

template<class _Myvec>
    class _Vector_iterator
        : public _Vector_const_iterator<_Myvec>
    {   // iterator for mutable vector
public:
    typedef _Vector_iterator<_Myvec> _Myiter;
    typedef _Vector_const_iterator<_Myvec> _Mybase;
    typedef random_access_iterator_tag iterator_category;

typedef typename _Myvec::value_type value_type;
typedef typename _Myvec::difference_type difference_type;
typedef typename _Myvec::pointer pointer;
typedef typename _Myvec::reference reference;
    ......

}</pre>

pointer定義,就是某個數據類型的指針

typedef value_type _FARQ *pointer;

再看下hashtable中的迭代器的定義:

......
struct _hashtable_iterator
{
    ......
    node* cur;
    hashtable* ht;
    .....
}

在hashtable迭代器中,有兩個指針,一是當前節點的指針,二是buckets vector的指針。

綜上所述,所謂迭代器,就是對指針以及其他輔助信息的一個封裝。對數據的訪問一定是通過地址訪問,地址是必須的,所以地址是迭代器中不可缺少的信息。
在迭代器的使用中,常常遇到的一個問題就是,在進行數據的插入刪除時的失效問題!其實就是指針的問題哈

Allocator(空間配置器):

空間配置器用于屏蔽容器關于內存管理的細節。比如容器內存的申請釋放,當內存不夠時采用怎樣的一種策略。在我們平常的使用中,

vector<strudent> stus;

并沒有制定容器的空間配置方案,于是采用默認的配置方案,其實我們是可以自己編寫空間配置方案,并將該方案實施于某個容器。(CustomAlloc是自定義的命名空間,并實現了空間配置方案allocator)
vector<int, CustomAlloc::allocator<int>> datas;

可以在自定義的方案中進行內存管理。

Algorithms(算法):

 提供了大量常用、通過的算法,比如比較、查詢、數據移動、復制、交換等等。
基礎算法:min, max, swap
排序:sort
替換:replace
查找:find
此處不一一列舉

Function Objects(函數對象):

函數對象,簡單的理解就是將一個函數封裝為對象,但是它的作用是為容器的操作提供依據。我進行比較大小,根據什么比,函數對象提供,查詢,匹配的規則是什么,函數對象提供。 
例如:

  1. 對vector容器進行排序,排序的標準是?
  2. 對容器中得數據進行查詢,查詢的標準是?
    通過函數對象,可以靈活的編寫操作依據,并注入到操作函數中。
    為sort函數編寫Compare()

    為find_if編寫Query()

    此處寫了個實例,說明一下用法:
    業務對象定義:

    class student
    {
    public:
        string name;
        int age;
    
        student(string name, int age)
        {
             this->name = name;
             this->age = age;
        }
    
        student(const student &stu)
        {
                *this = stu;
        }
    
        student& operator=(const student &stu)
        {
            this->name = stu.name;
            this->age = stu.age;
            return *this;
        }
    };

    函數對象定義,說明對象之間比較的依據,此處依據是年齡
    struct Compare : public std::binary_function<student, student, bool>
    {
    bool operator()(const student stu1, const student stu2) const
    {
            if (stu1.age < stu2.age)
                return true;
            else 
                return false;
    }
    };

    測試程序:
    int _tmain(int argc, _TCHAR* argv[])
    {
    vector<student> stus;
    srand((unsigned int)time(NULL));
    string strName = "student";
    for (int i = 0; i < 10; i++)
    {
        int val = rand()/10;
        char dataBuf[20];
        memset(dataBuf, 0, 20);
        itoa(val, dataBuf, 10);
        student stu(dataBuf, val);
        stus.push_back(stu);
    }
    
    for (vector<student>::iterator iter = stus.begin(); iter != stus.end(); iter++)
        cout<<iter->name<<"--"<< iter->age<<endl;
    cout<<"-----------------------------"<<endl;
    sort(stus.begin(), stus.end(),  Compare());
    for (vector<student>::iterator iter = stus.begin(); iter != stus.end(); iter++)
        cout<<iter->name<<"--"<< iter->age<<endl;
    
    getchar();
    return 0;
    }

    測試結果:將原本隨機插入的數據根據年齡進行了排序

     

     

     注:此處是對幾個組件的簡要說明,并未詳細深入

    轉自:http://my.oschina.net/myspaceNUAA/blog/78557

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!