STL

static變量在不同的對(duì)象

#include<iostream>

using namespace std;

template <typename T>

class Test{

public:

    static int _data;

    int a;

};

template<>int Test<int>::_data = 1;

template<>int Test<char>::_data = 2;

//static變量是屬于整個(gè)類(lèi),而不是某個(gè)對(duì)象

int main()

{

    cout<<Test<int>::_data<<endl;//1

    cout<<Test<char>::_data<<endl;//2

    Test<int> obji1,obji2;

    Test<char> objc1,objc2;

    cout<<obji1._data<<endl;//1

    cout<<obji2._data<<endl;//1

    cout<<objc1._data<<endl;//2

    cout<<objc2._data<<endl;//2

    obji1._data = 3;//_data = 3共同屬于obji1和obji2對(duì)象

    objc2._data = 4;

    cout<<obji1._data<<endl;//3

    cout<<obji2._data<<endl;//3

    cout<<objc1._data<<endl;//4

    cout<<objc2._data<<endl;//4

    obji1.a = 222;//a = 222是屬于obji1這個(gè)對(duì)象的,不屬于obji2對(duì)象

    cout<<obji1.a<<endl;//222

    cout<<obji2.a<<endl;//隨機(jī)

}

STL中的迭代器

template<class T>

class List{

public:

    void insert_front(T value);

    void insert_end(T value);

    void display() const();

    ListItem<T>* begin() const

    {

        return _front;

    }

    typedef ListIter<ListItem<T>> iterator;//所以說(shuō)迭代器是一個(gè)對(duì)象,是一個(gè)行為類(lèi)似指針的對(duì)象。和智能指針一樣,是個(gè)對(duì)象。

private:

    ListItem<T>* _end;

    ListItem<T>* _front;

    long _size;

};

template<class T>

class ListItem{

public:

    T value() const

    {

        return _value;

    }

    ListItem* next() const

    {

        return _next;

    }

private:

    T _value;

    ListItem<T>* _next;

};

template<class Item>

struct ListIter

{

    Item* ptr;

    ListIter(Item* p = NULL):ptr(p){}

    Item& operator *() const

    {

        return *ptr;

    }

    Item* operator ->() const

    {

        return ptr;

    }

    ListIter& operator ++()

    {

        ptr = ptr->next();

        return *this;

    }

    ListIter& operator ++(int)

    {

        ListIter tmp = *this;

        ++(*this);

        return temp;

    }

    bool operator ==(const ListIter &i) const

    {

        return ptr == i.ptr;

    }

    bool operator !=(const ListIter &i) const

    {

        return ptr != i.ptr;

    }

};

void main()

{

    List<int> myList;

    for(int i = 0;i < 5;++i)

    {

        myList.insert_front(i);

        myList.insert_end(i+2);

    }

    list<int>::iterator pd;

    pd = myList.begin();

}

類(lèi)模板中可以再有一個(gè)模板函數(shù)(class template中可以再有template(menbers))

#include<iostream>

using namespace std;

class alloc{

};

//迭代器的定義方法,其實(shí)迭代器是一個(gè)T類(lèi)型的指針 vector<int>::iterator pd. pd就是一個(gè)int類(lèi)型的指針。

template<class T,class Alloc = alloc>

class vector{

public:

    typedef T value_type;

    typedef value_type* iterator;

    template<class I>

    void insert(iterator position,I first,I last)

    {

        cout<<"insert()"<<endl;

    }

};

int main()

{

    int ia[5] = {0,1,2,3,4};

    vector<int> x;

    vector<int>::iterator ite;

    x.insert(ite,ia,ia+5);

}

template參數(shù)可以根據(jù)前一個(gè)template參數(shù)設(shè)定默認(rèn)值

#include<iostream>

using namespace std;

class alloc{

};

template<class T,class Alloc = alloc,size_t BufSiz = 0>

class deque{

public:

    deque(){cout<<"deque"<<endl;}

};

template<class T,class Sequence = deque<T>>//相當(dāng)于template<class T,class Sequence = deque<T,alloc,0>>

class stack{

public:

    stack(){cout<<"stack"<<endl;}

private:

    Sequence c;

};

int main()

{

    stack<int> x;//輸出 deque和stack

}

臨時(shí)對(duì)象的產(chǎn)生于運(yùn)用

template<class T>

class print{

public:

    void operator()(const T &elem)//注意若是重載運(yùn)算符(),函數(shù)定義為 print operator()(const T &elem)

    {

        cout<<elem<<' ';

    }

};

template<class T>

static void out(T n)

{

    cout<<n<<" ";

}

int main()

{

    int ia[6] = {0,1,2,3,4,5};

    vector<int> iv(ia,ia+6);

    //print<int>(iv.begin());//調(diào)用失敗

    for_each(iv.begin(),iv.end(),print<int>());//print<int>()是一個(gè)臨時(shí)對(duì)象,不是一個(gè)函數(shù)調(diào)用操作

    for_each(iv.begin(),iv.end(),out<int>);//平時(shí)都是使用這種方式調(diào)用。

}

STL空間配置器

在程序設(shè)計(jì)中,我們不免因?yàn)槌绦蛐枨螅褂煤芏嗟男K內(nèi)存(基本類(lèi)型以及小內(nèi)存的自定義類(lèi)型)。在程序中動(dòng)態(tài)申請(qǐng),釋放。這個(gè)過(guò)程過(guò)程并不是一定能夠控制好的,于是乎,

問(wèn)題1:就出現(xiàn)了內(nèi)存碎片問(wèn)題。(ps外碎片問(wèn)題)

問(wèn)題2:一直在因?yàn)樾K內(nèi)存而進(jìn)行內(nèi)存申請(qǐng),調(diào)用malloc,系統(tǒng)調(diào)用產(chǎn)生性能問(wèn)題。

注:內(nèi)碎片:因?yàn)閮?nèi)存對(duì)齊/訪問(wèn)效率(CPU取址次數(shù))而產(chǎn)生 如 用戶需要3字節(jié),實(shí)際得到4或者8字節(jié)的問(wèn)題,其中的碎片是浪費(fèi)掉的。

外碎片:系統(tǒng)中內(nèi)存總量足夠,但是不連續(xù),所以無(wú)法分配給用戶使用而產(chǎn)生的浪費(fèi)。

這兩個(gè)問(wèn)題解釋清楚之后,就來(lái)談STL空間配置器的實(shí)現(xiàn)細(xì)節(jié)了

實(shí)現(xiàn)策略

用戶申請(qǐng)空間大于128B?

yes:調(diào)用一級(jí)空間配置器

no:調(diào)用二級(jí)空間配置器

大致實(shí)現(xiàn)為:

二級(jí)空間配置由內(nèi)存池以及伙伴系統(tǒng):自由鏈表組成

一級(jí)空間配置器直接封裝malloc,free進(jìn)行處理,增加了C++中的set_handler機(jī)制(這里其實(shí)也就是個(gè)略顯牽強(qiáng)的裝飾/適配模式了),增加內(nèi)存分配時(shí)客戶端可選處理機(jī)制。

void MyOutOfMemory()

{

    cout << "Out of memory error!" << endl;

    abort();

}

int main()

{

    set_new_handler(MyOutOfMemory);

    int *verybigmemory = new int[0x1fffffff];//不能正常分配內(nèi)存的時(shí)候,調(diào)用MyOutOfMemory函數(shù)

    delete verybigmemory;

}

可配置性:

客戶端可以通過(guò)宏__USE_MALLOC進(jìn)行自定義選擇是否使用二級(jí)空間配置器。

一級(jí)空間配置器就主要封裝malloc,添加handler機(jī)制了,這里就不羅嗦了,相信各位都是可以通過(guò)源碼了解到的

[圖片上傳失敗...(image-8506b-1560669207937)]

image.png

偏特化和萃取

template<class T>

struct iterator_traites{

    typedef  T value_type;

};

template<class T>

struct iterator_traites<T *>{

    typedef  T value_type;

};

template<class T>

struct iterator_traites<const T *>{

    typedef  T value_type;

};

template<class T>

struct TraitsHelper{//注意這是一個(gè)普通的類(lèi)模板

    static const bool isPointer = false;

};

template<class T>

struct TraitsHelper<T*>{

    static const bool isPointer = true;

};

template <typename T>

class Test {

public:

    typedef typename iterator_traites<T>::value_type iv;

     iv Compute()

     {

         if(TraitsHelper<T>::isPointer)

             cout<<"is pointer"<<endl;

         else

             cout<<"not pointer"<<endl;

         iv k;//如果傳進(jìn)來(lái)的是指針,那么k就是一個(gè)指針,如果傳進(jìn)來(lái)的是普通類(lèi)型,那么k就是普通類(lèi)型。

         return k;

     }

private:

     T mData;

};

int main()

{

    Test<int *> t1;

    cout<<t1.Compute()<<endl;

}

STL中的配接器adapter

配接器(適配器)也是一種設(shè)計(jì)模式,在C++1中和單例模式都有介紹,是對(duì)某種方法的再封裝改造。官方解釋為:將一個(gè) class 的接口轉(zhuǎn)換為另一個(gè) class 的接口,使原本因接口不兼容而不能合作的 classes,可以一起運(yùn)作。一言以蔽之,Adapter 用于改變接口。

STL提供了三種適配器:

1.改變?nèi)萜鹘涌?,稱(chēng)之為container adapter

2.改變迭代器接口,稱(chēng)之為iterator adapter

3.改變仿函數(shù)接口,稱(chēng)之為function adapter

應(yīng)用于容器:queue和stack嚴(yán)格意義上來(lái)說(shuō)是配接器而不是容器,因?yàn)閝ueue和stack是對(duì)deque的再封裝(接口的改造)。

set和map(序列式容器)是對(duì)紅黑樹(shù)的再封裝(接口的改造)。

應(yīng)用于迭代器:

(1)insert iterators(2)reverse iterators(3)iostream iterators istream_iterator ostream_iterator

所謂 insert iterators,可以將一般迭代器的賦值(=,assign)操作變?yōu)椴迦耄╥nsert)操作。這樣的迭代器包括專(zhuān)司尾端插入操作back_insert_iterator,專(zhuān)司頭端插入的 front_insert_iterator,以及可在任意位置執(zhí)行插入操作的 insert_iterator。由于這三個(gè) iterator adapters 的使用接口不太直觀,給一般用戶帶來(lái)困擾,STL 提供三個(gè)相應(yīng)函數(shù),back_inserter_iterator()、front_inserter_iterator()、inserter_iterator()

template <typename Container>

class BackInsertIterator

{

public:

    typedef typename Container::value_type value_type;

    explicit BackInsertIterator(Container &cont)//類(lèi)屬性是一個(gè)容器,這個(gè)類(lèi)就是對(duì)這個(gè)容器操作

        :_cont(cont)

    { }

    BackInsertIterator<Container> &operator= (const value_type &val)

    {

        _cont.insert(_cont.end(), val);//其實(shí)還是調(diào)用了容器的插入操作(再封裝)

        return *this;

    }

    BackInsertIterator<Container> &operator*()

    { return *this; }

    BackInsertIterator<Container> &operator++()

    { return *this; }

    BackInsertIterator<Container> &operator++(int)

    { return *this; }

private:

    Container &_cont;

};

在使用的時(shí)候:

int main()

{

    char a[6]={'a','b','c','d','f','g'};

    vector <char> b(6);

    b.push_back('k');b.push_back('m');

    copy(a,a+4,back_insert_iterator< vector<char> >(b));

    for(int i = 0;i < b.size();++i)

        cout<<b[i]<<" ";

    return 0;

}

應(yīng)用于仿函數(shù):

functor adapters(亦稱(chēng)為 function adapters)是所有配接器中數(shù)量最為龐大的一個(gè)族群,其配接靈活程度也非前二者所能及,可以配接、配接、再配接。這些配接操作包括,

(1)系結(jié)(bind)、否定(negate)、組合(compose),

(2)以及對(duì)一般函數(shù)或成員函數(shù)的修飾(使其成為一個(gè)仿函數(shù))


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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