1.模板类遇上友元函数
//定义泛型
template <typename T>
class A
{
//这里要特别注意:只有在重载<< >>运算符的时候使用友元函数;其他情况都不要使用,
//因为会出现很奇怪的错误,不能滥用友元函数;
//再说了,什么时候回重写这两个运算符啊;
friend ostream& operator<< <T>(ostream & out, A& a);
public:
A(T a, T b)
{
this->a = a;
this->b = b;
}
A & operator+(A & a)
{
A tmp = A(a.a + this->a, a.b + this->b);
return tmp;
}
private :
T a;
T b;
};
template <typename T>
ostream& operator<<(ostream & out, A<T>& a)
{
out << a.b << endl;
return out;
}
void main()
{
A<int> a(1, 2);
A<int> a1(4,5);
A<int> a2 = a + a1;
cout << a2 << endl;
system("pause");
}
当模板类的函数声明和函数实现分开的时候,在使用这个类的时候要导入.cpp头文件不然函数的实现找不到。或者把cpp文件改成hpp文件意思就是吧cpp和h合二为一了;
2.当函数模板遇到静态成员变量的时候
静态成员变量是属于类的,所以对象共用的变量;以为泛型类或者模板类在创建对象的时候会从新创建一个具体数据类型的类,这个时候静态成员变量也会在创建一个,所以不同泛型的类会使用自己的静态成员变变量的;
//定义泛型
template <typename T>
class A
{
public:
//静态变量在内部初始化必须是常量;不然要在类的外部初始化
static T a;
private :
};
template <typename T>
T A<T>::a = 100;//静态成员变量必须在创建对象之前进行初始化;
void main()
{
A<int> aaa;
aaa.a = 1000;
cout << A<int>::a << endl;//输出1000;
A<char> bbbb;
bbbb.a = 'A';
cout << A<char>::a << endl;//输出'A';
//由此可见不同的泛型类的静态变量是不同的;不是共享的;
system("pause");
}
3.编写一个模板数组类,可以装int,char 和Teacher对象类型的数据
三个文件:.h .cpp main; 细节全在注释中,注意阅读
.h:
#pragma once
#include<iostream>
using namespace std;
template<typename T>
class MyVector
{
friend ostream& operator<< <T>(ostream & out, MyVector<T>& mv);
public:
MyVector(int len);
MyVector(const MyVector<T>& my);
~MyVector();
T& operator[](int index);
MyVector<T>& operator=(MyVector<T> & my);
int getLen()
{
return m_len;
}
private:
T * m_space;
int m_len;
};
.cpp:
#include "MyVector.h"
#include<iostream>
using namespace std;
//构造函数
template <typename T>
MyVector<T>::MyVector(int len)
{
this->m_len = len;
m_space = new T[m_len];
}
//拷贝构造函数
template <typename T>
MyVector<T>::MyVector(const MyVector<T>& my)
{
m_len = my.m_len;
m_space = new T[m_len];
for(int i=0;i<m_len;i++)
{
//这个地方不能使用重写的[];因为这个只能在类的外部使用;
m_space[i] = my.m_space[i];
//这个地方是数据拷贝,但是如果数据类型是类对象的话,就需要注意了
//类对象中可能有指针,就存在深浅拷贝问题;所以类要支持拷贝才行的;
//1.类要实现深拷贝;2,重载=号运算符;3.要重载<<运算符(当输出类对象的时候类型不支持的);
}
}
//析构函数
template <typename T>
MyVector<T>::~MyVector()
{
if (m_space!=NULL)
{
delete[] m_space;
m_space = NULL;
m_len = 0;
}
}
//重写[]运算符;这种重写只能在类的外部使用;
template <typename T>
T& MyVector<T>::operator[](int index)
{
return m_space[index];
}
template <typename T>
MyVector<T>& MyVector<T>::operator=(MyVector<T> & my)
{
//先释放本类的内存,因为两个对象分配内存大小可能不同;
if (m_space!=NULL)
{
delete[] m_space;
m_space = NULL;
m_len = 0;
}
//根据传进来的对象去申请内存
m_len = my.getLen();
m_space = new T[m_len];
//拷贝数据;
for (int i = 0; i<m_len; i++)
{
//这个地方不能使用重写的[];因为这个只能在类的外部使用;
m_space[i] = my.m_space[i];
//这个地方是数据拷贝,但是如果数据类型是类对象的话,就需要注意了
//类对象中可能有指针,就存在深浅拷贝问题;所以类要支持拷贝才行的;
//1.类要实现深拷贝;2,重载=号运算符;3.要重载<<运算符(当输出类对象的时候类型不支持的);
}
return *this;
}
template <typename T>
ostream& operator<<(ostream & out, MyVector<T>& mv)
{
for (int i=0;i<mv.getLen();i++)
{
out << mv[i] << "--";
}
out << endl;
return out;
}
main:
#include<iostream>
//因为有模板函数,导入头文件的是找不到函数的实现体的,必须要导入cpp;
#include "MyVector.cpp"
using namespace std;
void main()
{
MyVector<int> mv(10);
int i = 0;
for (i;i<mv.getLen();i++)
{
mv[i]=i+1;
cout << mv[i] << "--";
}
cout<< endl;
MyVector<int> mv2 = mv;
for (int i=0; i<mv2.getLen(); i++)
{
mv2[i] = i + 1;
cout << mv2[i] << "--";
}
cout << endl;
cout << mv2 << endl;
system("pause");
}