第60課-數組類模板


一、預備知識

模板參數可以是數值類參數(非類型參數)

template <typename T,int N>
void func(){
  T a[N];       //使用模板參數定義局部數組
}
···
func<double,10>();

數值型模板參數的限制

  • 變量不能作為模板參數
  • 浮點數不能作為模板參數
  • 類對象不能作為模板參數

本質:模板參數是在編譯階段被處理的單元,因此,在編譯階段必須准確無誤地唯一確定

編程實驗:有趣的面試題

#include<iostream>
using namespace std;

template < typename T,int N>
void func(){
    T a[N] = {0};
    for(int i = 0;i < N;++i){
        a[i] = i;
    }
    for(int i = 0;i < N;++i){
        cout << a[i] << endl;
    }
}

template <int N>
class Sum{
    public:
        static const int Value = Sum<N - 1>::Value + N;
};

template <>
class Sum <1>{
    public:
        static const int Value = 1;
};

int main(){
    cout << "1 + 2 + 3 + ···+ 10 = " << Sum<10>::Value << endl;
    cout << "1 + 2 + 3 + ···+ 100 = " << Sum<100>::Value << endl; 
    return 0;
} 

打印結果:

1 + 2 + 3 + ···+ 10 = 55 1 + 2 + 3 + ···+ 100 = 5050

總結:之所以認為其高效,是因為數值型模板參數實在編譯階段被處理的單元,也就是說Sum<10>::Value在編譯時就已經得出來了,程序實際運行時只是讀取“常量”罷了。

二、數組模板類

#ifndef _ARRAY_H_
#define _ARRAY_H_

template <typename T,int N>
class Array{
    T m_array[N];
    public:
        int length();
        bool set(int index,T value);
        bool get(int index,T& value);
        T& operator[](int index);
        T operator[] (int index) const;
        virtual ~Array();
};

template <typename T,int N>
int Array<T,N>::length(){
    return N;
}

template <typename T,int N>
bool Array<T,N>::set(int index,T value){
    bool ret = (0 <= index) && (index < N);
    if( ret ){
        m_array[index] = value;
    }
    return ret;
}

template <typename T,int N>
bool Array<T,N>::get(int index,T& value){
    bool ret = (0 <= index) && (index < N);
    if( ret){
        value = m_array[index];
    }
    return ret;
}

template <typename T,int N>
T Array<T,N>::operator[] (int index) const{
    return m_array[index];
}

template <typename T,int N>
Array<T,N>::~Array(){
}

#endif

三、堆數組模板類

#ifndef _HEAPARRAY_H_
#define _HEAPARRAY_H_

template <typename T>
class HeapArray{
    private:
        int m_length;
        T* m_pointer;

        HeapArray(int len);
        HeapArray(const HeapArray<T>& obj);
        bool construct();
    public:
        static HeapArray<T>* NewInstance(int length);
        int length();
        bool get(int index,T& value);
        bool set(int index,T value);
        T& operator [] (int index);
        T operator [] (int index) const;
        HeapArray<T>& self();
        ~HeapArray(); 
};

template <typename T>
HeapArray<T>::HeapArray(int len)
{
    m_length = len;
}

template <typename T>
bool HeapArray<T>::construct(){
    m_pointer = new T[m_length];
    return m_pointer != NULL;
}

template <typename T>
HeapArray<T>* HeapArray<T>::NewInstance(int length){
    HeapArray<T>* ret = new HeapArray<T>(length);
    if(!(ret && ret->construct())){
        delete ret;
        ret = 0;
    }
    return ret;
}

template <typename T>
int HeapArray<T>::length(){
    return m_length;
}

template <typename T>
bool HeapArray<T>::get(int index,T& value){
    bool ret = (0 <= index) && (index < length());
    if( ret ){
        value = m_pointer[index];
    }
    return ret;
}

template <typename T>
bool HeapArray<T>::set(int index,T value){
    bool ret = (0 <= index) && (index < length());
    if( ret ){
        m_pointer[index] = value;
    }
    return ret;
}

template <typename T>
T& HeapArray<T>::operator [] (int index){
    return m_pointer[index];
}

template <typename T>
T HeapArray<T>::operator [] (int index) const{
    return m_pointer[index];
}

template <typename T>
HeapArray<T>& HeapArray<T>::self(){
    return *this;
}

template <typename T>
HeapArray<T>& HeapArray<T>::self(){
    return *this;
}

template <typename T>
HeapArray<T>::~HeapArray(){
    delete[] m_pointer;
}

#endif

主函數:main.cpp

#include <iostream>
#include <string>
#include "Array.h"
#include "HeapArray.h"

using namespace std;

int main()
{
    Array<double, 5> ad;

    for(int i=0; i<ad.length(); i++)
    {
        ad[i] = i * i;
    }

    for(int i=0; i<ad.length(); i++)
    {
        cout << ad[i] << endl;
    }

    cout << endl;

    HeapArray<char>* pai = HeapArray<char>::NewInstance(10);

    if( pai != NULL )
    {
        HeapArray<char>& ai = pai->self();

        for(int i=0; i<ai.length(); i++)
        {
            ai[i] = i + 'a';
        }

        for(int i=0; i<ai.length(); i++)
        {
            cout << ai[i] << endl;
        }
    }

    delete pai;

    return 0;
}

四、總結

  • 模板參數可以是數值型參數
  • 數值型模板參數必須在編譯期間唯一確定
  • 數組類模板參數是基於數值型模板參數實現的
  • 數組類模板是簡易的線性表數據結構

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com