1.1 函数模板
#include<iostream>
using namespace std;
// 对字符数组,int排序
template <typename T, typename T1>
int mySort(T *arry, T1 size)
{
int temp;
if (arry == NULL)
return -1;
for (int i = 0; i < size;i++)
for (int j = i + 1; j < size; j++)
{
if (arry[i] < arry[j])
{
temp = arry[i];
arry[i] = arry[j];
arry[j] = temp;
}
}
return 0;
}
template <typename T, typename T1>
int myPrint(T *arry, T1 size)
{
T1 i;
for (i = 0; i < size; i++)
cout << arry[i] << " ";
return 0;
}
int main()
{
{
int myarry[] = { 11, 22, 10, 23, 20, 55 };
int size = sizeof(myarry) / sizeof(*myarry);
mySort<int, int>(myarry, size);//显示调用
//mySort(myarry, size);
printf("排序之后\n");
myPrint(myarry, size);//自动推导出
system("pause");
return 0;
}
//char类型
{
char buf[] = "hdffsfefdf";
int len = strlen(buf);
mySort<char,int>(buf, len);
myPrint<char,int>(buf, len);
system("pause");
return 0;
}
}
1.2 类模板
//complex.h
#include<iostream>
using namespace std;
template <typename T>
class Complex
{
friend Complex Mysub(Complex &c1, Complex &c2); //有元函数是全局函数,不属于这个类的
friend ostream& operator<< <T>(ostream &out, Complex &c3); //不加<T>报错LINK2019,两次编译每次生成的函数头不一样
public:
Complex(T a, T b);
void printCom();
Complex operator+(Complex &c2);
/*Complex operator-(Complex &c2);*/
protected:
private:
T a;
T b;
};
//complex.hpp
#include<iostream>
using namespace std;
#include "complex.h"
//构造函数写在类的外部..h和.cpp
template<typename T>
Complex<T>::Complex(T a, T b)
{
this->a = a;
this->b = b;
}
template<typename T>
void Complex<T>::printCom() //函数的名前加类的域名,因为他是成员函数
{
cout << "a:" << a << "b" << b << endl;
}
//成员函数,实现+运算符重载
template<typename T>
Complex<T> Complex<T>::operator+(Complex<T> &c2) //第一个是Complex<T>函数的返回值,参数也要具体化,名称也加域名;函数体内部要不要具体化无所谓
{
Complex temp(a + c2.a, b + c2.b);
return temp;
}
//成员函数,实现-运算符重载
//template<typename T>
//Complex<T> Complex<T>::operator-(Complex<T> &c2) //第一个是Complex<T>函数的返回值,参数也要具体化,名称也加域名;函数体内部要不要具体化无所谓
//{
// Complex temp(c1.a - c2.a, c1.b - c2.b);
// return temp;
//}
//友元函数实现<<重载
template<typename T>
ostream& operator<<(ostream &out, Complex<T>&c3) //全局函数,不属于类,不加域名
{
out << "a:" << c3.a << " b:" << c3.b << endl;
return out;
}
//友元函数实现-重载
template<typename T>
Complex<T> Mysub(Complex<T> &c1, Complex<T> &c2)
{
Complex temp(c1.a - c2.a, c1.b - c2.b);
return temp;
}
函数实现放在体内
#include<iostream>
using namespace std;
template <typename T>
class Complex
{
friend Complex Mysub(Complex &c1, Complex &c2)
{
Complex temp(c1.a - c2.a, c1.b - c2.b);
return temp;
}
//friend ostream& operator<<(ostream &out, Complex &c3);//函数体外实现
friend ostream& operator<<(ostream &out, Complex &c3)
{
out << "a:" << c3.a << " b:" << c3.b << endl;
return out;
}
public:
Complex(T a, T b )
{
this->a = a;
this->b = b;
}
//重载运算符
Complex operator+(Complex &c2)
{
Complex temp(a + c2.a, b + c2.b);
return temp;
}
void printCom()
{
cout << "a:" << a << "b" << b << endl;
}
protected:
private:
T a;
T b;
};
//ostream& operator<<(ostream &out, Complex &c3)
//{
// out << "a:" << c3.a << " b:" << c3.b << endl;
// return out;
//}
//测试代码
//#include "complex.h"
//#include "complex.cpp"//这里一点要注意了,要不然找不到函数体,两次编译惹的祸,所有常将cpp命名为hpp.与.h文件合二为一
#include "complex.hpp"
int main()
{ //需要将模板类具体化后,才能定义对象,C++编译器要分配内存
Complex<int> c1(1, 2);
Complex<int> c2(3, 4);
Complex<int> c3 = c1 + c2;
cout << c3 << endl;
//滥用友元
Complex <int> c4=Mysub(c1,c2);
cout << c4 << endl;
cout<<"hello..."<<endl;
system("pause");
return 0;
}
Example 2
//MyVector.h
#include<iostream>
using namespace std;
template<typename T>
class MyVector
{
friend ostream & operator<< <T>(ostream &out, const MyVector &obj);
public:
MyVector(int size = 0);
MyVector(const MyVector &obj);//拷贝构造函数
~MyVector();
public:
T& operator[](int index);//中括号重载
MyVector& operator=(const MyVector &obj);
public:
int getlen()
{
return m_len;
}
protected:
private:
T *m_space;
int m_len;
};
//MyVector.cpp
#include<iostream>
using namespace std;
#include "MyVector.h"
template<typename T>
ostream & operator<<(ostream &out, const MyVector<T> &obj)
{
for (int i = 0; i < obj.m_len; i++)
{
out << obj.m_space[i]<<" ";
}
cout << endl;//换行
return out;
}
//MyVector<int> myv1(10);构造函数
template<typename T>
MyVector<T>::MyVector(int size)
{
m_space = new T[size];
m_len = size;
}
//MyVector<int> myv2 = myv1;
template<typename T>
MyVector<T>::MyVector(const MyVector &obj)//拷贝构造函数根据myv1大小分配内存,cpy数据
{
m_len = obj.m_len;
m_space = obj.m_space;
for (int i = 0; i < obj.m_len; i++)
{
m_space[i] = obj.m_space[i];
}
}
template<typename T>
MyVector<T>::~MyVector()
{
if (m_space != NULL)
{
delete[]m_space;
m_space = NULL;//避免野指针
m_len;
}
}
template<typename T>
T& MyVector<T>::operator[](int index)//中括号重载
{
return m_space[index];
}
//a3=a2=a1
template<typename T>
MyVector<T>& MyVector<T>::operator=(const MyVector<T> &obj)
{
//先把a2的旧的内存释放掉
if (m_space != NULL)
{
delete[]m_space;
m_space = NULL;//避免野指针
m_len;
}
//根据a1分配内存
m_len = obj.m_len;
m_space = new T[m_len];
//copy数据
for (int i = 0; i < m_len;i++)
{
m_space[i] = obj.m_space[i];
}
return *this;//返回数组的引用,即a2;
}
//MyVector 测试代码
#include<iostream>
using namespace std;
#include "MyVector.cpp"
//#define _CRT_SECURE_NO_WARNINGS
class Teacher //1优化Teacher类,属性变成char *pname,构造函数里分配内存 2.析构函数释放pname指向的内存空间 3.避免浅拷贝,重载= ,重写拷贝函数 4,在teacher增加<<
{
public: //在模板数组类,存int char,Teacher, Teacher*;
Teacher()
{
age = 33;
//strcpy(name, "");
m_p = new char[1];
strcpy(m_p, "");
}
Teacher(char *name, int age)
{
this->age = age;
//strcpy(this->name, name);
m_p = new char[strlen(name) + 1];
strcpy(m_p, name);
}
Teacher(const Teacher &obj)
{
m_p = new char[strlen(obj.m_p) + 1];
strcpy(m_p, obj.m_p);
age = obj.age;
}
~Teacher()
{
if (m_p!=NULL)
{
delete[]m_p;
m_p = NULL;
}
}
void prinT()
{
//cout << name << "," << age << endl;
cout << m_p << "," << age << endl;
}
public:
friend ostream & operator<<(ostream &out, Teacher &t);
Teacher& operator=(const Teacher & obj)
{
if (m_p!=NULL)
{
delete[]m_p;
m_p = NULL;
age = 33;
}
m_p = new char[strlen(obj.m_p) + 1];
age = obj.age;
strcpy(m_p, obj.m_p);
return *this;
}
private:
int age;
//char name[32];
char *m_p; //深拷贝,和浅拷贝
};
ostream & operator<<(ostream &out, Teacher &t)
{
out << t.m_p << "," << t.age << endl;
return out;
}
void main()//存指针
{
Teacher t1("Li", 30), t2("YU", 24), t3("Zhao", 21);
MyVector<Teacher*>tArry(3);
tArry[0] = &t1; //t1丢进容器里面
tArry[1] = &t2;
tArry[2] = &t3;
for (int i = 0; i < 3; i++)
{
Teacher *tmp = tArry[i];
tmp->prinT();
}
//cout << tArry;//类对象没有实现左移,所以不能调用底层的<<重载
system("pause");
}
void main7()
{
MyVector<char> myv1(10);
myv1[0] = 'a';
myv1[1] = 'b';
cout << myv1;
system("pause");
}
int main6()
{
MyVector<int> myv1(10);
for (int i = 0; i < myv1.getlen(); i++)
{
myv1[i] = i + 1;
cout << myv1[i] << " ";
}
cout << endl;
MyVector<int> myv2 = myv1;
for (int i = 0; i < myv2.getlen(); i++)
{
cout << myv2[i] << " ";
}
cout << endl;
cout << myv2 << endl;//重载操作符
//operator<<(ostream &out,const MyVector &obj)
cout << "hello..." << endl;
system("pause");
return 0;
}