Essential c++ 第六章练习及类模板template class 知识点

版权声明:瞎几把写 https://blog.csdn.net/weixin_43184615/article/details/83096076

知识点
1、类模板形式 template< typename elemType> class T ,其中typename可以替换为class,写成template< class elemType> class T。 调用形式:T< string>t1

2、typename:用在模板定义里,标明其后的模板参数是类型参数。

3、常量表达式与默认参数值:Template的参数并不是非得某种类型不可,也可以用常量表达式(constant expression)作为参数。例如,template<int a,int b=1>class T,调用时为 T<32,1> t2.

4、Member Template Function(成员模板函数),即将类的成员函数定义成Template形式,其中类可以是普通类,也可以模板类。

5、new表达式和delete表达式:用以管理内存分配和释放。primer 12.1.2节详解。new返回一个指针,delete接收一个指针。

练习6.1

试改写以下类,使之成为一个class template:

class example{
public:
	example(double min, double max);
	example(const double *array, int size);
	double& operator[](int index);
	bool operator==(const example&) const;
	bool insert(const double*, int);
	bool insert(double);
	double min() const { return _min; }
	double max() const { return _max; }
	void min(double);
	void max(double);
	int count(double value) const;
private:
	int size;
	double *parray;
	double _max;
	double _min;
};

解:要将某个class转换为一个class template,我们必须找出所有和类型相关的部分,并且剥离出来。本例中,_size 的类型是int,用户会不会指定为其他类型呢?不会,因为 size用来记录 _parray所指数组的元素个数,其类型不会变动。至于_parray,就有可能指向不同类型的元素,如int ,double,float,string等,因此必须将_parray,_min,_max这些数据类型予以参数化。
由于elemType 现在可能被用来表现内置类型或class类型,因此以传址(by reference)方式而非传值(by value)方式比较好

template <typename elemType>
class example{
public:
	example(const elemType &min, const elemType &max);
	example(const elemType *array, int size);
	elemType& operator[](int index);
	bool operator==(const example&) const;
	bool insert(const elemType*, int);
	bool insert(const elemType&);
	elemType min() const { return _min; }
	elemType max() const { return _max; }
	void min(const elemType&);
	void max(const elemType&);
	int count(const elemType &value) const;
private:
	int size;
	elemType *parray;
	elemType _max;
	elemType _min;
};

tip:可以看到,模板类型下,凡是自定义数据类型的形参全部改成const T &a和const T *a,这是因为将内部数据类型(int ,double等)改成用户自定义数据类型后,对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。

练习6.2

将4.5的矩阵Matrix用template重写,使他能够通过堆内存来支持任意行列大小。分配/释放内存的操作请在constructor/destructor中进行。
知识点:new表达式分配动态数组~

#include<iostream>
using namespace std;

template<typename elemType>
class Matrix{
	//类模板中友函数声明前要再加上template<typename elemType>!!!不然会出现“无法解析的外部符号”错误
	template<typename elemType>
	friend Matrix<elemType> operator+(const Matrix<elemType>&, const Matrix<elemType>&);
	template<typename elemType>
	friend Matrix<elemType> operator*(const Matrix<elemType>&, const Matrix<elemType>&);

public:
	Matrix(int rows, int columns);
	//析构函数释放动态数组内存,要加[]
	~Matrix(){ delete[] _matrix; }
	//复制构造函数和复制赋值运算符
	Matrix(const Matrix&);
	Matrix& operator=(const Matrix&);

	void operator+=(const Matrix&);
	ostream& print(ostream &os)const;

	//函数调用运算符重载
	elemType& operator()(int row, int column){
		return _matrix[row*cols() + column];
	}
	elemType operator()(int row, int column)const{
		return _matrix[row*cols() + column];
	}

	int rows()const{ return _rows; }
	int cols()const{ return _cols; }


private:
	int _rows;
	int _cols;
	elemType *_matrix;
};

template<typename elemType>
inline ostream& operator<<(ostream &os, const Matrix<elemType> &m)
{
	return  m.print(os);
}

template<typename elemType>
ostream& Matrix<elemType>::print(ostream &os)const
{
	int col = cols();
	int matrix_size = col*rows();
	for (int ix = 0; ix < matrix_size; ++ix)
	{
		if (ix%col == 0) os << endl;
		os << (*(_matrix + ix)) << ' ';
	}
	os << endl;
	return os;
}

template<typename elemType>
Matrix<elemType>::Matrix(int rows, int columns)
         :_rows(rows), _cols(columns)
{
	int size = _rows*_cols;
	_matrix = new elemType[size]();// new表达式定义动态数组,加个()就可以实现初始化。
}

template<typename elemType>
Matrix<elemType>::Matrix(const Matrix &rhs)
{
	_rows = rhs._rows; _cols = rhs._cols;
	int matrix_size = _rows*_cols;
	_matrix = new elemType[matrix_size];
	for (int ix = 0; ix < matrix_size; ++ix)
		_matrix[ix] = rhs._matrix[ix];
}

template<typename elemType>
Matrix<elemType>& Matrix<elemType>::operator=(const Matrix &rhs)
{
	if (this != &rhs)
	{
		_rows = rhs._rows; _cols = rhs._cols;
		int matrix_size = _rows*_cols;
		delete[] _matrix;
		_matrix = new elemType[matrix_size];
		for (int ix = 0; ix < matrix_size; ++ix)
			_matrix[ix] = rhs._matrix[ix];
	}
	return *this;
}

template<typename elemType>
Matrix<elemType> operator+(const Matrix<elemType> &m1, const Matrix<elemType> &m2)
{
	Matrix<elemType> result(m1.rows(), m1.cols());
	for (int ix = 0; ix < m1.rows(); ++ix)
	{
		for (int jx = 0; jx < m1.cols(); ++jx)
		{
			result(ix, jx) = 0;
			result(ix, jx) = m1(ix, jx)+m2(ix,jx);
		}
	}
	return result;
}

template<typename elemType>
Matrix<elemType> operator*(const Matrix<elemType> &m1, const Matrix<elemType> &m2)
{
	Matrix<elemType> result(m1.rows(), m2.cols());
	for (int ix = 0; ix < m1.rows(); ++ix)
	{
		for (int jx = 0; jx < m1.cols(); ++jx)
		{
			result(ix, jx) = 0;
			for (int kx = 0; kx < m1.cols();++kx)
			     result(ix, jx) += m1(ix, kx) * m2(kx, jx);
		}
	}
	return result;
}

template<typename elemType>
void Matrix<elemType>::operator+=(const Matrix &m)
{
	int matrix_size = cols()*rows();
	for (int ix = 0; ix < matrix_size; ++ix)
		(*(_matrix + ix)) += (*(m._matrix + ix));
}

int main()
{
	Matrix<float>identity(4, 4);
	cout << "identity: " << identity << endl;

	float ar[16] = { 1., 0., 0., 0., 0., 1., 0., 0.,
		0., 0., 1., 0., 0., 0., 0., 1. };
	for (int i = 0, k = 0; i < 4;++i)
	for (int j = 0; j < 4; ++j)
		identity(i, j) = ar[k++];
	cout << "identity after set: " << identity << endl;

	Matrix<float> m(identity);
	cout << "m " << m << endl;

	Matrix<float> m2(8, 12);
	cout << "m2 " << m2 << endl;

	m2 = m;
	cout << "m2=m " << m2 << endl;

	float ar2[16] = { 1.3, 0.4, 2.6, 8.2, 6.2, 1.7, 1.3, 8.3,
		4.2, 7.4, 2.7, 1.9, 6.3, 8.1, 5.6, 6.6 };
	Matrix<float> m3(4, 4);
	for (int ix = 0, kx = 0; ix < 4; ++ix)
	for (int j = 0; j < 4; ++j)
		m3(ix, j) = ar2[kx++];
	cout << "m3 " << m3 << endl;
	
	Matrix<float>m4 = m3*identity; cout << "m4 "<<m4 << endl;
	Matrix<float>m5 = m3 + m4; cout << "m5 " << m5 << endl;

	m3 += m4; cout << m3 << endl;

	system("pause");
}

猜你喜欢

转载自blog.csdn.net/weixin_43184615/article/details/83096076
今日推荐