类模板的派生
类模板和普通类一样也可以继承和派生,以实现代码复用,类模板的派生一般有三种情况:类模板派生普通类、类模板派生类模板、普通类派生类模板,这三种派生关系可以解决很多实际问题,接下来我们就针对这三种派生关系进行讲解。
1、类模板派生普通类
在C++中,可以从任意一个类模板派生一个普通类。在派生中,作为非模板类的基类,必须是类模板实例化后的模板类,示例代码如下所示:
template<typename T>
class A //类模板
{
private:
T x;
T y;
public:
A();
A(T x, T y);
T getx();
T gety();
~A();
};
class B : public A<double> //普通类B公有继承类模板A
{
private:
double num;
public:
B(double a, double b, double c) :num(c), A<double>(a, b){}
};
在这段示例代码中,类模板A派生出了普通类B,其实在这个派生过程中类模板A先实例化出了一个double类型的具体类,然后由这个具体类派生出类B,因此在派生过程中需要指定模板形参类型。 根据这个派生关系可以从类模板创建具体的类,而不是让编译器自动创建那些不满足要求的类。
2、类模板派生类模板
从类模板派生出一个新的类模板,它和普通类之间的派生几乎完全相同,例如下面的例子,从类模板A派生出一个类模板B:
template<typename T>
class A
{
T a;
public:
A(int n):a(n){}
int getA() const { return a; }
};
template<typename T, typename U>
class B : public A<U>
{
U b;
public:
B(T t, U u) :A<T>(t), b(u){}
U sum() const{ return b + (U)getA(); }
};
B类模板由类模板A派生而得出,B的数据成员和成员函数类型仍由类模板参数U确定,因此B仍然是一个模板。类模板派生类模板技术可以用来构建类模板的层次结构。
3、普通类派生类模板
从普通类派生出类模板可以把现存类库中的类转换为通用的类模板,但这需要对技术非常了解,本书只对它作一个简单示例,代码如下所示:
class A
{
int a;
public:
A(int n) :a(n){}
int getA() const { return a; }
};
template<typename T>
class B : public A
{
T b;
public:
B(int n, T t) :A(n), b(t){}
T sum() const { return b + (T)getA(); }
};
在上述示例中,类A是一个普通类,由它派生出了类模板B,利用这种技术,程序员能够从现存类中创建类模板,由此可以创建基于非类模板库的类模板。