GoF本のためのC++入門 (その5)
前回に引き続き、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
って感じでいちいち頭にくっつけないといけないみたい(めんどうだ)。まあこれで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
うん、ちゃんと追加したのとは逆順で取り出せてる。
というわけで、テンプレートを使うとクラスの定義と型の種別を分離できるよ、って話でした。