C++ template classとは?テンプレートクラス

始めに、テンプレートがどういった機能なのかは、
テンプレートとは?で説明しています。

また、テンプレート関数については、
テンプレート関数で説明しています。


テンプレート機能は関数にも使えましたが、クラスにも適用できます。

テンプレートクラス

テンプレート機能を付加したクラスをテンプレートクラスと言います。

#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が使われます。