C++学习笔记(17)——简析类模板

在《函数探幽》一文中总结了函数模板的相关的知识。我们大概知道模板提供了泛型编程的便利,也即我们可以用通用的类型来定义表征一系列类型,比如函数的形参。对于类,我们也可以设计一种通用的类型的类来实现代码的重用。本文将总结类模板的相关知识。

1.定义类模板

与模板函数类似,模板类也要以下面的代码开头:

template <class T>

这与函数模板的功能一样,也即声明T为一种通用类型。当然,这里的class并不是说后面的T必须为一个类,class可以换为typename。这里我们设计一个复数类。复数类的实部和虚部可以是整型和浮点型数据,因此模板可以很好的满足应用需求。

可以将类的成员变量和成员函数都声明为模板接口。比如Complex的实部和虚部,以及它重载四则运算的函数接口。但注意,在接口的是西安时(方法定义时)要在每个函数前面都要添加template <class T>,且要在类的作用域标识符前添加<T>.同时,不能将模板成员函数放在独立的实现文件中,所以通常我们把他们和类的声明一起写在头文件中。其中,若函数的实现是以内联函数的形式出现,则不必再函数前重复添加template <class T>。

2.使用模板类

与模板函数一样,再具体使用模板类时需进行实例化。也即使用具体的类型来替换泛型名。如:

Complex<int> iComplex(1,2);

Complex<float> fComplex(3.5,2.2);

其实际过程时用int或float替换类定义中所有的T。就如函数模板,类的模板也可以隐式实例化,显式实例化和显式具体化,相关的内容请参考函数探幽中的总结。

3.模板类与友元

我们想为Complex重载<<运算符以打印复数,鉴于之前的知识,我们知道需要通过友元来重载<<运算符。自然的想法是在类中添加声明:

friend std::ostream & operator<<(std::ostream & os, const Complex & c);//复数打印

具体定义为:

template <class T>

std::ostream & operator<<(std::ostream & os, const Complex<T> & c)

{

   os << c.a << "+" << c.b <<"i";

   return os;

}

如果你尝试这么做了,但是发现编译报错了。问题在于并没有完成具体化工作。我们需要修改的工作只需要在友元函数的声明处添加template <class T>模板头,也即将友元函数声明为函数模板,这样在具体化过程中即每个函数的具体化都是每个具体化的友元。这被称作模板类的非约束友元函数。

四、源码

#ifndef TEMPLATE_H
#define TEMPLATE_H

#include <iostream>

template <class T>
class Complex
{

private:
	T a;	//实部
	T b;	//虚部

public:
	//构造函数
	Complex(T a = 0, T b = 0);
	//接口函数
	T Real(){return a;};	//内联函数不必用template <class T>
	T Imag(){return b;};	//内联函数不必用template <class T>
	Complex  operator+(Complex &c);	//运算符重载

	//友元重载<<
	template <class T> friend std::ostream & operator<<(std::ostream & os, const Complex & c);//复数打印
};


//构造函数 需要有模板头
template <class T>
Complex<T>::Complex(T a, T b)
{
	this->a = a;
	this->b = b;
}

//运算符重载
template <class T>
Complex<T> Complex<T>::operator+(Complex<T> &c)
{
	Complex<T> tmp(this->a+c.a, this->b+c.b);
	return tmp;
}

//显示 重载<<  注意也需使用模板头
template <class T>
std::ostream & operator<<(std::ostream & os, const Complex<T> & c)
{
	os << c.a << "+" << c.b <<"i";
	return os; 
}

#endif
发布了76 篇原创文章 · 获赞 63 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/bjtuwayne/article/details/85858529
今日推荐