栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2021/10/9 C++Primer Plus 类模板

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021/10/9 C++Primer Plus 类模板

示例导入:

//vectorTemplateClass.h -- create my vector class template 
#pragma once
#include
#include

template
class Vector
{
protected:
	T *array;
	int m_len;

public:
	//Default Constructor
	Vector();
	//Copy constructor
    Vector(const Vector& temp);
	//Destructor
	~Vector();

	//overload operator methods
	Vector operator+(const Vector& v)const;
	Vector& operator+=(const Vector& v);
	Vector operator-(const Vector& v)const;
	Vector& operator-=(const Vector& v);
	Vector operator-()const;
	T operator*(const Vector& v)const;
	Vector operator*(T per)const;
	Vector& operator=(const Vector& v);
	T& operator[](int i);
	T operator[](int i)const;

	//friend methods
	template friend bool operator==(const Vector& v1, const Vector& v2);
	template friend bool operator!=(const Vector& v1, const Vector& v2);
	template friend std::ostream& operator<<(std::ostream& os, const Vector& v);
	template friend std::istream& operator>>(std::istream& is, Vector& v);
	//template friend Vector& operator*(T per, const Vector& v);

	//common class methods
	void reverse();
	void swap(Vector& v);
	int size() { return m_len; }
	int find(T n);
	Vector& resize(int size, T n);
	void clear();
	T pop();
	double distance();
};

//Default Constructor
template
Vector::Vector()
{
	m_len = 0;
	array = new T[1];
	array = NULL;
}

//Copy Constructor
template
Vector::Vector(const Vector& temp)
{
	m_len = temp.m_len;
	array = new T[m_len];
	for (int i = 0; i < temp.m_len; i++)
		array[i] = temp.array[i];
}

//Destructor
template
Vector::~Vector()
{
	delete[] array;
}

//overload operator+
template
Vector Vector::operator+(const Vector& v)const
{
	if (m_len != v.m_len)
	{
		std::cerr << "Dimensions are inconsistent: " << std::endl;
		std::cerr << "One dimensions is " << m_len << ", the other is " << v.m_len << std::endl;
		std::exit(EXIT_FAILURE);
	}
	Vector v2;
	v2.m_len = m_len;
	v2.array = new T[m_len];
	for (int i = 0; i < m_len; i++)
		v2.array[i] = array[i] + v.array[i];
	return v2;
}

//overload operator +=
template
Vector& Vector::operator+=(const Vector& v)
{
	if (m_len != v.m_len)
	{
		std::cerr << "Dimensions are inconsistent: " << std::endl;
		std::cerr << "One dimensions is " << m_len << ", the other is " << v.m_len << std::endl;
		std::exit(EXIT_FAILURE);
	}
	for (int i = 0; i < m_len; i++)
		array[i] += v.array[i];
	return *this;
}

//overload operator - 
template
Vector Vector::operator-(const Vector& v)const
{
	if (m_len != v.m_len)
	{
		std::cerr << "Dimensions are inconsistent: " << std::endl;
		std::cerr << "One dimensions is " << m_len << ", the other is " << v.m_len << std::endl;
		std::exit(EXIT_FAILURE);
	}
	Vector v2;
	v2.m_len = m_len;
	v2.array = new T[m_len];
	for (int i = 0; i < m_len; i++)
		v2.array[i] = array[i] - v.array[i];
	return v2;
}

//overload operator -=
template
Vector& Vector::operator-=(const Vector& v)
{
	if (m_len != v.m_len)
	{
		std::cerr << "Dimensions are inconsistent: " << std::endl;
		std::cerr << "One dimensions is " << m_len << ", the other is " << v.m_len << std::endl;
		std::exit(EXIT_FAILURE);
	}
	for (int i = 0; i < m_len; i++)
		array[i] -= v.array[i];
	return *this;
}

//overload operator-(Contary vector)
template
Vector Vector::operator-()const
{
	Vector v;
	v.m_len = m_len;
	v.array = new T[m_len];
	for (int i = 0; i < m_len; i++)
		v.array[i] = -array[i];
	return v;
}

//overload operator*(dot metrix)
template
T Vector::operator*(const Vector& v)const
{
	if (m_len != v.m_len)
	{
		std::cerr << "Dimensions are inconsistent: " << std::endl;
		std::cerr << "One dimensions is " << m_len << ", the other is " << v.m_len << std::endl;
		std::exit(EXIT_FAILURE);
	}
	T sum = 0;
	for (int i = 0; i < m_len; i++)
		sum += array[i] * v.array[i];
	return sum;
}

//overload operator*
template
Vector Vector::operator*(T per)const
{
	Vector v;
	v.m_len = m_len;
	v.array = new T[m_len];
	for (int i = 0; i < m_len; i++)
		v.array[i] = array[i] * per;
	return v;
}

//overload operator=
template
Vector& Vector::operator=(const Vector& v)
{
	if (*this == v)
		return *this;
	delete[] array;
	m_len = v.m_len;
	array = new T[m_len];
	for (int i = 0; i < v.m_len; i++)
		array[i] = v.array[i];
}

//revisable
template
T& Vector::operator[](int i)
{
	if (i >= m_len || i <= -m_len)
	{
		std::cerr << "Error in array limits: " << i << "is out of range!" << std::endl;
		std::exit(EXIT_FAILURE);
	}
	if (i < 0)
		return array[m_len + i];
	return array[i];
}

//unchangeable
template
T Vector::operator[](int i)const
{
	if (i >= m_len || i <= -m_len)
	{
		std::cerr << "Error in array limits: " << i << "is out of range!" << std::endl;
		std::exit(EXIT_FAILURE);
	}
	if (i < 0)
		return array[m_len + i];
	return array[i];
}

//friend methods
template
bool operator==(const Vector& v1, const Vector& v2)
{
	bool flag = true;
	if (v1.m_len != v2.m_len)
		return !flag;
	for (int i = 0; i < v1.m_len; i++)
	{
		if (v1.array[i] != v2.array[i])
			return !flag;
	}
	return flag;
}

template
bool operator!=(const Vector& v1, const Vector& v2)
{
	bool flag = true;
	if (v1.m_len != v2.m_len)
		return flag;
	for (int i = 0; i < v1.m_len; i++)
	{
		if (v1.array[i] != v2.array[i])
			return flag;
	}
	return !flag;
}

template
std::ostream& operator<<(std::ostream& os, const Vector& v)
{
	if (v.m_len <= 0)
		return os;
	os << "(";
	if (v.m_len > 1)
	{
		for (int i = 0; i < v.m_len - 1; i++)
			os << v.array[i] << ", ";
		os << v.array[v.m_len - 1] << ")";
	}
	else
		os << v.array[v.m_len - 1] << ")";
	return os;
}

template
std::istream& operator>>(std::istream& is, Vector& v)
{
	std::cout << "Please enter dimension:  ";
	is >> v.m_len;
	v.array = new T[v.m_len];
	std::cout << "Please input the vector:  ";
	for (int i = 0; i < v.m_len; i++)
		is >> v.array[i];
	return is;
}

//template
//Vector& operator*(T per, const Vector& v)
//{
//	return v * per;
//}

template
void Vector::reverse()
{
	if (m_len != 0)
	{
		for (int i = 0;; i++)
		{
			T temp = array[i];
			array[i] = array[m_len - i - 1];
			array[m_len - i - 1] = temp;
			if (i >= m_len - i - 1)
				break;
		}
	}
}

template
void Vector::swap(Vector& v)
{
	Vector temp;
	temp = v;
	v = *this;
	*this = temp;
}

template
int Vector::find(T n)
{
	if (m_len != 0)
		for (int i = 0; i < m_len; i++)
			if (array[i] == n)
				return i + 1;
	std::cout << "Can't find " << n << " in vector!" << std::endl;
	return 0;
}

template
Vector& Vector::resize(int size, T n)
{
	delete[]array;
	m_len = size;
	array = new T[m_len];
	for (int i = 0; i < m_len; i++)
		array[i] = n;
	return *this;
}

template
void Vector::clear()
{
	delete[]array;
	array = NULL;
	m_len = 0;
}

template
T Vector::pop()
{
	T temp = array[m_len - 1];
	delete array[m_len - 1];
	m_len--;
	return temp;
}

template
double Vector::distance()
{
	T sum = 0;
	for (int i = 0; i < m_len; i++)
		sum += array[i];
	return sqrt(sum);
}

注释:

1.类开头、友元函数前以及类外定义方法时需要声明泛型名称Type

template

而在类声明中定义了方法(内敛定义),则可以省略模板前缀和类限定符。

2.不可以将模板成员函数放在独立的实现文件中,因为模板不是函数,不能单独编译,同时在使用

前不占用内存,只有在被实例化或具体化后才会有自己的内存空间。

3.模板类友元函数声明和定义前都需要声明泛型名称,如:

	template friend std::ostream& operator<<(std::ostream& os, const Vector& v);

4.模板类函数在定义时,返回类型、域名、参数数据类型都需要泛型名称,而在类中声明时为

Stack,这是Stack

Stack & operator=(const Stack & st)

   ……

template 
Stack & Stack::operator=(const Stack & st)

5.如果要在类声明中声明数组,在具体化时就确定数组元素个数,则可以有以下声明:

template 
class ArrayTP
{
 private:
    T arr[n];
 ……

使用类模板时数据类型可以用ArrayTP

6.模板类也可以用作基类,在继承时的用法类似,仅仅需要在继承声明时加上模板类的数据类型声

明,同时也可有虚函数如:

virtual T & operator[](int i);

7.模板类也可以用作其他模板的类型参数,即可以递归使用:

ArrayTP< ArrayTP, 10> twodes;

与之等价的常规数组的声明为int twodes[10][5];

若无数组维数,则两个>之间至少需要一个空白字符将其分开,防止与>>混淆:

Array< Stack > asi;

8.在类模板实例化时,调用构造函数以及声明域名都需要的时类似于Stack这种,因为类名

是Stack而不是Stack;

9.隐式实例化:声明一个或多个对象,指出所需类型,而编译器使用通用模板提供的处方生成具体

的类定义

ArrayTp * pt;       #1
pt = new ArrayTp    #2

第一条语句只是指针,并不需要对象,因此不会生成类定义,而第二条语句导致编译器生成类定义

并且根据该定义创建一个对象。

显示实例化:需要用到关键字template

template class ArrayTP;

虽然没有创建或提及类对象,编译器也将会生成类定义

10.部分具体化

template  class Pair

11.嵌套模板

template 
class beta
{
    private:
       template 
       class hold;
       hold q;
       hold n;
    ……
    ……
template 
  template 
     U beta::blab(U u, T t>
     {
        return (n.Value() + q.Value * u /t;
     }

12.模板类的约束模板友元函数即将友元函数声明为模板:

//类定义前声明每个模板函数
   ……
template  void counts();
template  void report(T &);

   ……

//在类方法中再次将模板声明为友元
template 
class class_name
{
   ……
   friend void counts();
   friend void report<>(class_name &);
   ……
//友元函数定义
    ……

13.模板别名:

关键字typedef类型:typedef std::array arrd;

关键字using类型:using arrtype = std::array;

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号