發新話題

C++ Gossip《範本、名稱空間》 類別範本

C++ Gossip《範本、名稱空間》 類別範本

可以在C++中使用「類別範本」(Class template),又稱「通用類別」(Generic class),舉個例子來說,曾經介紹過如何撰寫一個自訂的陣列類別(以 訪客無法瀏覽此圖片或連結,請先 註冊登入會員 中的SafeArray為例),當時該類別很明顯的,只能用於建立int型態的陣列,如果您想要使用於double、char或其它資料型態,難道要一一建立這些類別嗎?當然不是,您可以宣告類別為類別範本,讓我們的程式碼撰寫可以提高重覆使用。

要宣告一個類別成為樣版類別,您可以這麼宣告:
template <class 型態名稱>
class 類別名稱{
    // ........
};


在類別定義外部定義的樣版函式(在::之前加上<型態名稱>),以及如何使用樣版類別建立物件,這邊直接使用實例來介紹:
  • SafeArray.h
#include "ArrayIndexOutOfBoundsException.h"

template <class CType>
class SafeArray {
public:
    // 建構函式
    SafeArray(int);
    // 解構函式
    ~SafeArray();
   
    CType get(int);
    void set(int, CType);
   
    int length;
private:
    CType *_array;        

    bool isSafe(int i);  
};

// 動態配置陣列
template <class CType>
SafeArray<CType>::SafeArray(int len) {
    length = len;
    _array = new CType[length];
}

// 測試是否超出陣列長度
template <class CType>
bool SafeArray<CType>::isSafe(int i) {
    //
    if(i >= length || i < 0) {
         return false;
    }
    else {
         return true;
    }
}

// 取得陣列元素值
template <class CType>
CType SafeArray<CType>::get(int i) {
    if(isSafe(i)) {
        return _array;        
    }
    else {
        // 存取超過陣列長度,丟出例外
        throw ArrayIndexOutOfBoundsException(i);         
    }
}

// 設定陣列元素值
template <class CType>
void SafeArray<CType>::set(int i, CType value) {
    if(isSafe(i)) {
        _array = value;
    }
    else {
        // 存取超過陣列長度,丟出例外
        throw ArrayIndexOutOfBoundsException(i);   
    }
}

// 刪除動態配置的資源
template <class CType>
SafeArray<CType>::~SafeArray() {
    delete [] _array;
}
您還需要訪客無法瀏覽此圖片或連結,請先 註冊登入會員 中的Exception與ArrayIndexOutOfBoundsException類別,一個使用SafeArray類別範本的例子如下:
  • main.cpp
#include <iostream>
#include "SafeArray.h"
#include "Exception.h"
#include "ArrayIndexOutOfBoundsException.h"
using namespace std;

int main() {
    SafeArray<int> safeArray1(10);
    SafeArray<double> safeArray2(10);
   
    try {
        for(int i = 0; i < safeArray1.length; i++) {
            safeArray1.set(i, (i + 1) * 10);
        }
   
        for(int i = 0; i < safeArray1.length; i++) {
            cout << safeArray1.get(i) << " ";
        }

        cout << endl;

        for(int i = 0; i < safeArray2.length; i++) {
            safeArray2.set(i, (i + 1) * 0.1);
        }
   
        for(int i = 0; i < safeArray2.length; i++) {
            cout << safeArray2.get(i) << " ";
        }
   
        cout << endl;
    }
    catch(ArrayIndexOutOfBoundsException e) {
        cout << endl
             << e.message()
             << endl;
    }
    catch(Exception e) {
        cout << endl
             << e.message()
             << endl;
    }
   
    return 0;
}
執行結果:
10 20 30 40 50 60 70 80 90 100
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

在這個例子中,您可以分別建立一個物件內部成員為int與double型態的SafeArray實例,但不用為它們個別撰寫不同的類別,這可以讓我們所定義的類別更具有通用性。

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。