【C++】模版的概念、使用方法和深入瞭解

    模板是泛型編程的基礎。所謂泛型編程就是編寫與類型無關的邏輯代碼,是一種複用的方式。模板分爲模板函數和模板類。

    模板函數

假設現在要實現一個比較兩個數是否相等的重載函數。

bool IsEqual (int left, int right)
{
     return left == right;
}

bool IsEqual (const string& left , const string& right)
{
     return left == right;
}

void test1 ()
{
     string s1 ("s1"), s2("s2");
     cout<<IsEqual (s1, s2)<<endl;
     cout<<IsEqual (1,1)<<endl;
}

    從代碼可以看出,如果我們要比較int和char類型需要分別編寫程序來解決這兩個問題,所以代碼的重複度就會很高,所以C++中就引入了模版來解決這個問題。

    模板形參的定義既可以使用class,也可以使用typename,含義是相同的。上面的問題就可以簡化爲如下的代碼:

template<class T>
bool IsEqual(const T& left, const T& right)
{
    return left == right;
}

void test1 ()
{
     string s1 ("s1"), s2("s2" );
     cout<<IsEqual (s1, s2)<<endl ;
     cout<<IsEqual (1,1)<<endl;
}

對於T的類型,編譯器自己會通過推演得到T的類型,從而做出應有的處理。


    在這,重點分享下模版的深入知識。

template<typename T>
class SeqList
{
public:
    SeqList()
        :_array(NULL)
        , _size(0)
        , _capacity(0)
    {}
    
    ~SeqList()
    {
        if (_array)
        {
            delete[] _array;
        }
    }

    SeqList(const SeqList<T>& s)
    {
        _array = new T[s._size];
        //memcpy(_array, s._array, sizeof(T)*s._size);

        for (size_t i = 0; i < s._size; i++)//根據size的大小來,原空間多大,同樣拷貝多大的空間
        {
            _array[i] = s._array[i];
        }

        _size = s._size;
        _capacity = s._capacity;
    }

    SeqList<T>& operator=(SeqList<T> s)
    {
        swap(_array, s._array);
        swap(_size, s._size);
        swap(_capacity, s._capacity);

        return *this;
    }

    void PushBack(const T& x)
    {
        _CheckCapacity();
        _array[_size++] = x;
    }

    void Print()
    {
        for (int i = 0; i < _size; ++i)
        {
            cout << _array[i] << " ";
        }
        cout << endl;
    }

    void Reserve(size_t x)
    {
        _CheckCapacity(x);
    }

    T& operator[](size_t index)
    {
        assert(index < _size);

        return _array[index];//如果不用引用,那麼傳過來的是一塊臨時空間,只是將臨時空間的值給覆蓋了,如果使用引用那麼就是把對應的空間給出來,賦值的時候直接在原基礎上改動
    }
    
protected:
    void _CheckCapacity(size_t n)
    {
        if (n > _capacity)
        {
            _capacity = 2 * _capacity + 3 > n ? 2 * _capacity + 3 : n;
            /*_array = (T*)realloc(_array, sizeof(T)*_capacity);*/

            T* tmp = new T[_capacity];
            if (_array)
                /*memcpy(tmp, _array, sizeof(T)*_size);*/ 
            for (size_t i = 0; i < _size; i++)
            {
                tmp[i] = _array[i];
            }

            delete[] _array;
            _array = tmp;
        }
    }

private:
    T* _array;
    size_t _size;
    size_t _capacity;
};

//template<typename T>  //在模版內聲明,在模版外定義與C++代碼寫順序表的區別
//void SeqList<T>::PushBack(const T& x)//作用域要寫類型名,而不是類名
//{
//    
//}

void test1()
{
    SeqList<int>s1;
    s1.PushBack(1);
    s1.PushBack(2);
    s1.PushBack(3);
    s1.PushBack(4);

    s1.Print();

    SeqList<string> s2;
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");

    s2.Print();

    SeqList<string> s3(s2);
    s3.Print();

    SeqList<string> s4;
    s4.PushBack("yyy");

    s4 = s3;
    s4.Print();
    //string* p1 = (string*)malloc(sizeof(string));//指向的是字符串類,字符串類裏面不僅僅只包含了字符串指針,還有_size,_capacity等內容
    //string* p2 = new string;

    //*p1 = "sss";
    //*p2 = "sss";

}

int main()
{
    test1();
    system("pause");
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章