クラステンプレートの使用と詳細
私たちは異なるタイプのパラメータのクラスを書くとき、特にコンテナクラスでは、保存したいオブジェクトのタイプが異なる以外に、コードが同じであることを望んでいます.このとき、私たちは汎型のクラスを望んでいます.私たちは毎回実現するのではなく、具体的なタイプをパラメータの形式で伝えることができます.
c++のクラステンプレートは、汎用的なクラス宣言を生成するのに良い方法を提供します.これもコード再利用の重要な一部です.
まず、テンプレートクラスをどのように定義しますか.
template
キーワードtemplateは、テンプレートを定義するコンパイラに伝えます.括弧の内容はパラメータリストに相当し,キーワードclassは変数のタイプ名,Typeは変数の名前と見なす.
もちろんclassを使用することはクラスのみをパラメータとすることを意味するわけではありません.これはTypeが一般的なタイプ説明子であることを示しています.テンプレートのインスタンス化では、特定のタイプを使用して置き換えることになります.また、classの代わりにtypenameを使用することもできます.
template
重要な概念は次のとおりです.
テンプレートはクラスでもメンバー関数でもありません.クラスとメンバー関数の生成方法を説明するc++コンパイラ命令にすぎません.テンプレートの具体的な実装は、インスタンス化と具体化によって行われる.
テンプレート情報は一般的にヘッダファイルに格納され、使用時にヘッダファイルが含まれます.
次に、テンプレートクラスを使用する方法について説明します.パラメータとして特定のタイプのオブジェクトを宣言する必要があります.
例えば、Stackst; Stack st2;
Intを使用してTypeを置き換え、doubleを使用してTypeを置き換えます.
タイプパラメータを割り当てるのはタイプのみで、数値ではありません.必要なタイプを表示する必要があります.
テンプレートクラスの拡張:
1、テンプレート内の非タイプパラメータの使用
template
キーワードclassはTをタイプパラメータ,intはnのタイプをIntとし,このパラメータを非タイプパラメータ(式パラメータ)と呼ぶ.
式パラメータにはいくつかの制限があります.式パラメータは、整数、列挙、参照、ポインタです.テンプレートコードは、パラメータの値を変更したり、パラメータのアドレスを使用したりすることはできません.例えばn+,&nなどです.
2、テンプレートの多機能性
再帰使用テンプレート:配列テンプレートArrayの場合、Array,10>twodee;
これにより、10個の要素を含む配列が得られ、各要素は5個のInt要素を含む配列である.
テンプレートには、templateという複数のタイプのパラメータが含まれます.
デフォルトタイプパラメータテンプレート:templateclass topo;
インスタンス化時にT 2を省略すると、コンパイラはintを使用します.
テンプレートの具体化:
具体化は暗黙的にインスタンス化し、インスタンス化を表示し、具体化を表示し、部分的に具体化することができます.
1、暗黙的なインスタンス化
必要なタイプを指定し、1つ以上のオブジェクトを宣言します.主な目的はオブジェクトの作成です.
pt = new Array;
コンパイラはクラス定義を生成し、定義に基づいてオブジェクトを作成します.
2、インスタンス化を表示
キーワードtemplateを使用して、クラスを宣言するために必要なタイプを指定します.
template class Array;
オブジェクトは作成されず、クラス宣言のみが生成されます.
3、具体化表示
特定のタイプの定義です.汎用定義テンプレートとは異なり、特定の定義を持つテンプレート
template <> class Array(const char *) {...};
これはchar*タイプ専用のテンプレートです.
コンパイラは、インスタンス化時に、インスタンス化テンプレートと汎用テンプレートがインスタンス化と一致する場合に、インスタンス化テンプレートを優先的に使用するという原則に従います.
4、部分具体化
タイプパラメータのいずれかに特定のタイプを指定します.
template class Pair {...};
キーワードtemplateの後の<>宣言には具体化されていないタイプのパラメータがありますが、空の場合は表示具体化、
template <> class Pair {...};
複数のテンプレートを選択できる場合、コンパイラは最も具体化されたテンプレートを使用します.
テンプレートの使用シーン:
1、テンプレートをメンバーにする
これはbetaテンプレートでholdメソッドを宣言し定義し、qメンバーはタイプTに基づくholdオブジェクトである.
betaテンプレートでholdメソッドを宣言すると、外部で定義するとテンプレートネストが表示されます.
2、テンプレートをパラメータとして
テンプレートには、それ自体がテンプレートであるパラメータを含めることができます.
template class Thing>
class Crab{
Thing s1;
Thing s2;
...
};
template
class King{
...
};
テンプレートパラメータはemplateclass Thingです.ThingをKIngで置き換えます.
テンプレートと友元:
テンプレートの友元は、非テンプレート友元、コンストレイントテンプレート友元、非コンストレイントテンプレート友元の3つに分類されます.
1、テンプレート以外の友元
テンプレートクラスの一般的な関数を友元として宣言します.テンプレートのすべてのインスタンス化された友元と呼ばれます.
友元関数にテンプレートクラスパラメータを提供し、使用する場合は具体化を表示する必要があります.
template
class HasFriend{
pulbic:
friend void reports(HasFriend &);
...
};
void reports(HasFriend & hf){ }
void reprots(HasFriend & hf) {}
Report()はテンプレート関数ではなく、テンプレートクラスパラメータを使用して定義する場合、特定のタイプに渡す必要があります.上記で定義した2つのreport()関数は、それぞれ2つの特定のHasFriendが具体化した友元である.
2,テンプレートクラスの制約テンプレート友元関数
友元関数はテンプレートとなり、友元タイプはクラスがインスタンス化されたタイプに依存します.
template void couts();
template void reports(T &);//最初のステップでは、テンプレート関数を宣言します.
template
class HasFriend{
friend void couts ();//ステップ2テンプレートを友元として宣言する
friend void reports<> (HasFriend &);
};
template//第3歩、テンプレート定義を提供
void couts{
cout << ... << endl;
}
couts()関数にはパラメータがないので、<>を使用して具体化タイプを指定します.reports()関数にはパラメータがあり、パラメータからテンプレートタイプパラメータを推定できるので、<>は空にできます.
使用時、couts()、couts()、
HasFriend hf1;
HasFrined hf2;
reports(hf1);//関数パラメータタイプによる
reports(hf2);
3、非拘束テンプレート友元関数
クラス内でテンプレートを宣言すると、各関数の具体化は各クラスの具体化の友元です.
tempalet
class Many{
templatefriend void show(C & ,D &);
};
template void show(C & c,D & d){
cout << .. << endl;
}
show()関数はすべての具体化された友元である.
これらのメカニズムは、テストされたコードを再利用できるようにするためです.
c++のクラステンプレートは、汎用的なクラス宣言を生成するのに良い方法を提供します.これもコード再利用の重要な一部です.
まず、テンプレートクラスをどのように定義しますか.
template
キーワードtemplateは、テンプレートを定義するコンパイラに伝えます.括弧の内容はパラメータリストに相当し,キーワードclassは変数のタイプ名,Typeは変数の名前と見なす.
もちろんclassを使用することはクラスのみをパラメータとすることを意味するわけではありません.これはTypeが一般的なタイプ説明子であることを示しています.テンプレートのインスタンス化では、特定のタイプを使用して置き換えることになります.また、classの代わりにtypenameを使用することもできます.
template
<span style="font-size:18px;">template <class Type>
class Stack{
private:
Type items[10];
int top;
public:
Stack();
bool push(const Type & item);
...
};
template <class Type> //
Stack<Type>::Stack(){ //
top = 0;
}
template <class Type>
bool Stack<Type>::push(const Type & item){
...
}</span>
重要な概念は次のとおりです.
テンプレートはクラスでもメンバー関数でもありません.クラスとメンバー関数の生成方法を説明するc++コンパイラ命令にすぎません.テンプレートの具体的な実装は、インスタンス化と具体化によって行われる.
テンプレート情報は一般的にヘッダファイルに格納され、使用時にヘッダファイルが含まれます.
次に、テンプレートクラスを使用する方法について説明します.パラメータとして特定のタイプのオブジェクトを宣言する必要があります.
例えば、Stack
Intを使用してTypeを置き換え、doubleを使用してTypeを置き換えます.
タイプパラメータを割り当てるのはタイプのみで、数値ではありません.必要なタイプを表示する必要があります.
テンプレートクラスの拡張:
1、テンプレート内の非タイプパラメータの使用
template
キーワードclassはTをタイプパラメータ,intはnのタイプをIntとし,このパラメータを非タイプパラメータ(式パラメータ)と呼ぶ.
式パラメータにはいくつかの制限があります.式パラメータは、整数、列挙、参照、ポインタです.テンプレートコードは、パラメータの値を変更したり、パラメータのアドレスを使用したりすることはできません.例えばn+,&nなどです.
2、テンプレートの多機能性
再帰使用テンプレート:配列テンプレートArrayの場合、Array
これにより、10個の要素を含む配列が得られ、各要素は5個のInt要素を含む配列である.
テンプレートには、template
デフォルトタイプパラメータテンプレート:template
インスタンス化時にT 2を省略すると、コンパイラはintを使用します.
テンプレートの具体化:
具体化は暗黙的にインスタンス化し、インスタンス化を表示し、具体化を表示し、部分的に具体化することができます.
1、暗黙的なインスタンス化
必要なタイプを指定し、1つ以上のオブジェクトを宣言します.主な目的はオブジェクトの作成です.
pt = new Array
コンパイラはクラス定義を生成し、定義に基づいてオブジェクトを作成します.
2、インスタンス化を表示
キーワードtemplateを使用して、クラスを宣言するために必要なタイプを指定します.
template class Array
オブジェクトは作成されず、クラス宣言のみが生成されます.
3、具体化表示
特定のタイプの定義です.汎用定義テンプレートとは異なり、特定の定義を持つテンプレート
template <> class Array(const char *) {...};
これはchar*タイプ専用のテンプレートです.
コンパイラは、インスタンス化時に、インスタンス化テンプレートと汎用テンプレートがインスタンス化と一致する場合に、インスタンス化テンプレートを優先的に使用するという原則に従います.
4、部分具体化
タイプパラメータのいずれかに特定のタイプを指定します.
template
キーワードtemplateの後の<>宣言には具体化されていないタイプのパラメータがありますが、空の場合は表示具体化、
template <> class Pair
複数のテンプレートを選択できる場合、コンパイラは最も具体化されたテンプレートを使用します.
テンプレートの使用シーン:
1、テンプレートをメンバーにする
template <class T>
class Bete{
private:
template <class V>
class hold{
private:
V val;
public:
hold(V v = 0):val(v){ }
void show() const {cout << val << endl;}
};
hold <T> q;
hold <int > n;
public:
beta(T t,int i):q(t),n(i){}
...
};
これはbetaテンプレートでholdメソッドを宣言し定義し、qメンバーはタイプTに基づくholdオブジェクトである.
betaテンプレートでholdメソッドを宣言すると、外部で定義するとテンプレートネストが表示されます.
tempate <class T>
class Bete{
private:
template <class V>
class hold;
hold<T> q;
hold <int> n;
...
};
template <class T>
template <class V>
class Bete<T>::hold{
private:
V val;
public:
...
};
2、テンプレートをパラメータとして
テンプレートには、それ自体がテンプレートであるパラメータを含めることができます.
template class Thing>
class Crab{
Thing
Thing
...
};
template
class King{
...
};
テンプレートパラメータはemplate
テンプレートと友元:
テンプレートの友元は、非テンプレート友元、コンストレイントテンプレート友元、非コンストレイントテンプレート友元の3つに分類されます.
1、テンプレート以外の友元
テンプレートクラスの一般的な関数を友元として宣言します.テンプレートのすべてのインスタンス化された友元と呼ばれます.
友元関数にテンプレートクラスパラメータを提供し、使用する場合は具体化を表示する必要があります.
template
class HasFriend{
pulbic:
friend void reports(HasFriend
...
};
void reports(HasFriend
void reprots(HasFriend
Report()はテンプレート関数ではなく、テンプレートクラスパラメータを使用して定義する場合、特定のタイプに渡す必要があります.上記で定義した2つのreport()関数は、それぞれ2つの特定のHasFriendが具体化した友元である.
2,テンプレートクラスの制約テンプレート友元関数
友元関数はテンプレートとなり、友元タイプはクラスがインスタンス化されたタイプに依存します.
template
template
template
class HasFriend{
friend void couts ();//ステップ2テンプレートを友元として宣言する
friend void reports<> (HasFriend &);
};
template
void couts{
cout << ... << endl;
}
couts()関数にはパラメータがないので、<>を使用して具体化タイプを指定します.reports()関数にはパラメータがあり、パラメータからテンプレートタイプパラメータを推定できるので、<>は空にできます.
使用時、couts
HasFriend
HasFrined
reports(hf1);//関数パラメータタイプによる
reports(hf2);
3、非拘束テンプレート友元関数
クラス内でテンプレートを宣言すると、各関数の具体化は各クラスの具体化の友元です.
tempalet
class Many{
template
};
template
cout << .. << endl;
}
show()関数はすべての具体化された友元である.
これらのメカニズムは、テストされたコードを再利用できるようにするためです.