読者です 読者をやめる 読者になる 読者になる

GoF本のためのC++入門 (その5)

C++ 連載

前回に引き続き、GoFデザインパターン本(オブジェクト指向における再利用のためのデザインパターン)に載っているサンプルコードを読むためにC++を勉強してる。

今日のお題はテンプレートクラス。こいつを使うと、int型でもdouble型でも何でもOKなスタッククラス、みたいな感じで、汎用的な型を使用したクラスを定義できる。

早速、以下のページを参考にして試してみた。
C++編(言語解説) 第27章 テンプレートクラス

#include <iostream>
#include <string>

using namespace std;

// スタッククラス
template <class T>
class Stack {
public:
    Stack();
    bool isEmpty();
    void push(T);
    T pop();
private:
    T items[100];
    int count;
};

template ってところがテンプレートクラスを作るために足した所ね。このTが具体的にどういう型なのかは、この時点では確定していない。何か知らないけど、とりあえず使用できる。あと、Tって名前は別に何でも良い。GoF本だとItemって名前を使ってるね。

次にメソッドの実装。

// メソッドの実装
template <class T>
Stack<T>::Stack()
{
    count = 0;
}

template <class T>
bool Stack<T>::isEmpty()
{
    return count == 0;
}

template <class T>
void Stack<T>::push(T item)
{
    if (count < 100) {
        items[count] = item;
        count++;
    }
}

template <class T>
T Stack<T>::pop()
{
    T ret = 0;
    if (not isEmpty()) {
        ret = items[count - 1];
        count--;
    }
    return ret;
}

template Stack::* って感じでいちいち頭にくっつけないといけないみたい(めんどうだ)。まあこれでOKっぽいので、こいつを使ってみる。

int main()
{
    Stack<int> s;
    // こんな風にnewできなかった
    //Stack<int>* s = new Stack<int>();

    s.push(5);
    s.push(12);
    s.push(13);

    while(not s.isEmpty()) {
        cout << s.pop() << endl;
    }

    return 0;
}

ここで Stack と宣言してるので、さっきTとか言ってうやむやにしてた型が確定する。ここがintじゃなくてdoubleとかでも上のクラスの定義を変えなくていい、ってとこがポイントね。あと、newするやりかたでもできるかなと思ったけど、無理だった。

出力はこんな感じ。

13
12
5

うん、ちゃんと追加したのとは逆順で取り出せてる。

というわけで、テンプレートを使うとクラスの定義と型の種別を分離できるよ、って話でした。

< 前へ
この連載の一覧