テンプレートを理解する上で、用語をわかりやすくすることは、テンプレートについて話す方法がテンプレートの考え方を決定するため、非常に有利です。
具体的にAreaは、はテンプレートクラスではなく、クラステンプレートです。つまり、クラスを生成できるテンプレートです。Area<int>そのようなクラスです(これはオブジェクトではありませんが、他のクラスからオブジェクトを作成するのと同じ方法で、そのクラスからオブジェクトを作成できます)。別のそのようなクラスになりますArea<char>。これらは完全に異なるクラスであり、同じクラステンプレートから生成されたという事実以外は共通点がないことに注意してください。
以来Areaクラスではありません、あなたはクラスを派生することはできませんRectangleそれから。別のクラス(またはそれらのいくつか)からのみクラスを派生できます。Area<int>はクラスなので、たとえば、次のように派生できますRectangle。
class Rectangle:
public Area<int>
{
// ...
};
以来Area<int>とArea<char>異なるクラスで、あなたも(それらのメンバーにアクセスするときただし、あいまいさに対処する必要があります)同時に両方から派生することができます。
class Rectangle:
public Area<int>,
public Area<char>
{
// ...
};
ただし、定義するときに、どのクラスから派生するかを指定する必要がありますRectangle。これは、これらのクラスがテンプレートから生成されるかどうかに関係なく当てはまります。同じクラスの2つのオブジェクトが異なる継承階層を持つことはできません。
Rectangleテンプレートを作成することもできます。あなたが書くなら
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
RectangleからRectangle<int>派生するクラスを取得できるテンプレートArea<int>と、から派生する別のクラスがRectangle<char>ありますArea<char>。
同じ関数にRectangleすべての種類を渡すことができるように単一のタイプRectangleが必要な場合があります(それ自体がエリアタイプを知る必要はありません)。Rectangle<T>テンプレートのインスタンス化によって生成されたクラスRectangleは、形式的には互いに独立しているため、そのようには機能しません。ただし、ここでは多重継承を利用できます。
class Rectangle // not inheriting from any Area type
{
// Area independent interface
};
template<typename T> class SpecificRectangle:
public Rectangle,
public Area<T>
{
// Area dependent stuff
};
void foo(Rectangle&); // A function which works with generic rectangles
int main()
{
SpecificRectangle<int> intrect;
foo(intrect);
SpecificRectangle<char> charrect;
foo(charrect);
}
ジェネリックRectangleがジェネリックから派生していることが重要な場合は、次の方法AreaでAreaも同じトリックを実行できます。
class Area
{
// generic Area interface
};
class Rectangle:
public virtual Area // virtual because of "diamond inheritance"
{
// generic rectangle interface
};
template<typename T> class SpecificArea:
public virtual Area
{
// specific implementation of Area for type T
};
template<typename T> class SpecificRectangle:
public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later
public SpecificArea<T> // no virtual inheritance needed here
{
// specific implementation of Rectangle for type T
};