C++进阶STL-模板

模板的机制

模板并不是能处理任何类型的数据,只是它根据传入参数的类型的不同生成了不同的 函数/类 体(我们在不使用函数模板的正常操作,只不过编译器帮我们做了)。在此编译过程中,存在两次编译,一次是模板,一次是实例化的函数/类。


函数模板的定义

template <class V1,class V2…>// 或者 template < typename V1….> 告诉编译器 遇到变量V不要报错,可定义多个 V1 , V2……
void Exchange ( V1 a  , V1 b)
{
    V1 c=a;
       a=b;
       b=c;
}


函数模板的作用范围:

只对后面第一个函数有效

函数模板的调用

  • 自动类型推导
int a=10, b=0;
Exchange(a,b);
  • 显示的指定类型
Exchange<int>(a,b);

函数模板与普通函数的区别

  • 普通函数在传参的时候可以进行类型转换。
  • 函数模板在传参的时候 参数的类型必须一致

函数模板与普通函数的优先级

  • 函数模板和普通函数同时存在且满足需求的时候,优先考虑普通函数。
  • 如果非得调用模板函数,在调用函数名后加<>。

定义类模板

  • 通常类模板的申明和定义写在同一文件,命名为.hpp,表明有类模板的文件。其他使用文件需要包含此.hpp
  • 类中每个函数将如下定义
Template<class T>
Student<T>::Student()
{

}

类模板必须显示调用

Student <int> S1(1,2);

类模板的派生

子类在派生父类的时候,必须先确定父类的类型

template<class T>
class Student
{
		
   private: T m_name;
}
//情况1,父类确定好类型
class Person:public Student<int>
{
}
//情况2,再重新定义个模板
template<class T>
class Person:public Student< T >
{
}


友元函数

  • (1) 类前申明
    template<class T1, class T2> class Student;
    template<class T1, class T2> void Print(Student<T1, T2> p);
  • (2)类中声明
    friend void Print<T1,T2>(Student<T1, T2> p);
  • (3)定义处
    template<class T1, class T2>
    void Print(Student<T1, T2> p)
    {
      cout << “name is :” << p.m_name << “age is:” << p.m_age << endl;
    }

重载操作符在类模板中申明为友元

  • 类前申明:
    template<class T1, class T2> class Student;
    template<class T1, class T2> ostrream& operator<< (ostrream& os Student<T1, T2> &p);
  • 类的申明:
    template<class T1, class T2>
    class Student
    {
      friend ostream& operator<< < T1, T2> (ostrream& os ,Student<T1, T2> &p);
    }
  • 定义处:
    template<class T1, class T2>
    ostrream& operator<< < T1, T2> (ostrream& os ,Student<T1, T2> &p);
    {
      重载函数实现
    }

类模板中申明static变量,每个实例化的类拥有各自的static变量,不进行共享,

student.hpp

template <class T>
class Student
{
public:
static int a;
}

template <class T>
int Student< T >::a = 0; //初始化

main.cpp

Student<int> p;
	p.a = 10;
	Student<char> p1;
	p1.a = 100;
	cout << "p.a :" << p.a << endl;      //输出10
	cout << "p1.a :" << p1.a << endl;    //输出100     p和p1虽然都是由模板来,但不共享


模板的例子:

#include "stdafx.h"
#include "iostream"
using namespace std;

//1.对象元素必须能够被拷贝  =操作符重载,默认拷贝构造是浅拷贝
//容器是将对象拷贝一份放进去的,而不是将对象本身放进去的
//拷贝中注意 深拷贝 浅拷贝的问题

template <class T>
class MyArray
{
public:
	MyArray(int capacity)
	{
		this->m_Capacity = capacity;
		this->m_Size = 0;
		m_pArrd = new T[capacity];
	}
	//拷贝构造
	MyArray(const MyArray<T>& array1)
	{
		this->m_Capacity = array1.m_Capacity;
		this->m_Size = array1.m_Size;
		this->m_pArrd = new T[array1.m_Capacity];
		for (int i = 0; i < array1.m_Size; i++)
		{
			this->m_pArrd[i] = array1.m_pArrd[i];
		}
		cout << "拷贝构造" << endl;
	}
	//[]重载
	T& operator [](int index)
	{
		return this->m_pArrd[index];
	}

	//等号操作符重载
	MyArray<T>& operator =(const MyArray<T>& array1)
	{
		if (this->m_pArrd != NULL)
		{
			delete []this->m_pArrd;
		}

		this->m_Capacity = array1.m_Capacity;
		this->m_Size = array1.m_Size;
		this->m_pArrd = new T[array1.m_Capacity];

		for (int i = 0; i < array1.m_Size; i++)
		{
			this->m_pArrd[i] = array1.m_pArrd[i];
		}
		cout << "重载操作符" << endl;
		return *this;
	}
	//对左值取引用	
	void PushBack(T& var)
	{
		if (this->m_Size >= this->m_Capacity)
			return;
		else
		{
			this->m_pArrd[this->m_Size] = var;
			this->m_Size++;
		}

	}
	//对右值取引用(直接可以传数值)
	void PushBack(T&& var)
	{
		if (this->m_Size == this->m_Capacity)
			return;
		else
		{
			this->m_pArrd[this->m_Size] = var;
			this->m_Size++;
		}
	}
	~MyArray()
	{
		if (this->m_pArrd != NULL)
			delete []this->m_pArrd;
	}

private:
	int m_Capacity;
	int m_Size;
	T*  m_pArrd;
};




int main()
{
	MyArray <int> Array(10);
	int a = 1, b = 2, c = 3, d = 4;
	Array.PushBack(a);
	Array.PushBack(b);
	Array.PushBack(c);
	Array.PushBack(d);

	for (int i = 0; i < 4; i++)
	{
		cout << Array[i] <<" ";
	}
	cout << endl;




	MyArray <int> Array1(5);
	Array1 = Array;//    等号操作符重载
	Array1.PushBack(5);  //右值作为引用
	for (int i = 0; i < 5; i++)
	{
		cout << Array1[i] << " ";
	}
	cout << endl;


	MyArray <int> Array2=Array1;//拷贝构造
	Array2[4] = 5;// []重载
	for (int i = 0; i < 5; i++)
	{
		cout << Array2[i] << " ";
	}
	cout << endl;



    return 0;
}


猜你喜欢

转载自blog.csdn.net/zzyczzyc/article/details/82932148