始めに、テンプレートがどういった機能なのかは、
テンプレートとは?で説明しています。
また、テンプレート関数については、
テンプレート関数で説明しています。
テンプレート機能は関数にも使えましたが、クラスにも適用できます。
テンプレートクラス
テンプレート機能を付加したクラスをテンプレートクラスと言います。
#include <iostream>
using namespace std;
template <typename T> class myclass {
public:
T data;
void show() {
cout << data << '\n';
}
};
void main() {
myclass<int> obj;
obj.show();
}
このプログラムは、メンバ変数を1つ持ち、
そのメンバ変数の値を出力する単純なクラスを使ったモノです。
メンバ変数のデータ型が
いろいろなデータ型に対応できるようになっています。
また、テンプレートクラスのインスタンスを作成する場合には、
クラス名の後に<>でデータ型情報を指定しなければなりません。
new演算子を使った場合や、配列を扱う場合の例
// new演算子
myclass<int>* p = new myclass<int>;
p->show();
delete p;
// new演算子と配列
myclass<int>* p = new myclass<int>[3];
p[0].show(); または p->show();
p[1].show(); または (p+1)->show();
p[2].show(); または (p+2)->show();
delete [] p;
いろいろな使い方
また、typenameを使う型情報を複数定義したり、
固定のデータ型を使う事も可能です。
#include <iostream>
using namespace std;
template <typename T1, typename T2, int idata> class myclass {
public:
T1 data1;
T2 data2;
void show() {
cout << data1 << '\n';
cout << data2 << '\n';
cout << idata << '\n';
}
};
void main() {
myclass<int, double, 10> obj;
obj.show();
}
省略可能引数のような機能
関数には、省略可能引数と言う機能がありましたが、
テンプレートクラスにも似たような機能があります。
#include <iostream>
using namespace std;
template <typename T=int, int idata=10> class myclass {
public:
T data;
void show() {
cout << data << '\n';
cout << idata << '\n';
}
};
void main() {
myclass<> obj; // <int, 10>で処理される
myclass<double> obj; // <double, 10>で処理される
myclass<double, 5> obj; // <double, 5>で処理される
myclass<, 5> obj; // エラー
obj.show();
}
また、関数の時と同じように、
省略できる引数は後ろに置かなければなりません。
下記のように記述すると、
テンプレートクラスのインスタンスを作れなくなります。
template <typename T1=int, int idata> class myclass {
テンプレートクラスのメンバ関数の定義について
(テンプレート)クラスの内容が大きくなると
ヘッダファイルとソースファイルに分割する事が多くなりますが、
その場合、メンバ関数の定義の際に注意点があります。
ファイル名:myclass.h
template <typename T> class myclass {
public:
T data;
void show();
};
ファイル名:myclass.cpp
#include <iostream>
#include "myclass.h"
using namespace std;
template <typename T> void myclass<T>::show() {
cout << data << '\n';
}
このプログラムは、クラス定義を分割した例です。
メンバ関数showが記述されているファイルが
クラス定義と別ファイルなので、
書かなくてはならない部分が少し増えます。
テンプレートクラスの多重定義
テンプレートクラスは、どのデータ型にも対応するクラスですが、
特定のデータ型の時だけ、違う処理をさせたい場合があります。
こんな場合には、テンプレートクラスを多重定義します。
#include <iostream>
using namespace std;
template <typename T> class myclass {
public:
T data;
void show() {
cout << data << '\n';
}
};
template<> class myclass<double> {
public:
double data;
void show() {
cout << "double型=" << data << '\n';
}
};
void main() {
myclass<int> obj;
obj.show();
myclass<double> Dobj;
Dobj.show();
}
このプログラムでは、
myclassテンプレートクラスが多重定義されています。
与えられたデータ型がdouble型の時だけは、
double対応のmyclassが使われます。