泛型
C++中用模板来实现泛型(将变量类型作为函数参数,以实现代码的复用)
函数模板
痛点:写一个add函数实现加法功能,要实现整型,浮点型,Point型(自定义)加法,就需要重写3次add
int add(int a,int b);
double add(double a, double b);
Point add(Point p1, Point p2);
采用函数模板则可以优化代码>>
template <typename T>
T add(T a, T b)
{
return a + b;
}
调用add时候指明类型或者不指明类型都可以
int main()
{
add<int>(10, 20);
add(0.5, 1.3);
add<Point>(Point(5, 5), Point(3, 2));
return 0;
}
如果想接受不同的类型参数,可以写成:
template <typename T,typename A,typename B>
T add(A a, B b)
{
return a + b;
}
调用时候指明参数类型
int main()
{
add<double,int,double>(10, 5.5);
return 0;
}
注意:模板函数实现和调用分开写会报链接错误。因为分开写的话,编译器会分开编译两个cpp文件,由于在写函数实现的cpp中没有调用函数,没有指明输入参数类型,所以不会产生函数地址,在调用函数的cpp中调用时,找不到函数入口,就会报链接错误。
如果是不用模板则不会出现链接错误,因为不用模板时,函数实现明确了输入参数类型,在实现时就产生 了函数地址,在调用的cpp中能找到入口。
解决办法: 把类里面的函数声明和实现现在yige.hpp文件里面
类模板
需求:下面的代码是一个动态数组,但是只能存放int数据,如果想要存放其他类型,采用类模板
class Array
{
private:
int *m_data;//指向首元素的指针
int m_size;//当前元素个数
int m_capacity;//能容纳元素的容量
public:
Array(int capacity)
{
m_capacity = (capacity >0) ? capacity:10;
m_data = new int[m_capacity] {};
}
~Array()
{
if (m_data == NULL) return;
delete[] m_data;
}
void add(int value)
{
if (m_size == m_capacity)
{
int *tmp = m_data;
int *m_data = new int[m_capacity + 1];
for (int i = 0; i <= m_size; i++) {
*(m_data +i) = *(tmp+i);
}
delete[] tmp;
}
m_data[m_size++] = value;
}
int get(int index)
{
if (index < 0 || index >= m_size) {
cout << "越界" << endl;
return -1;
};
return m_data[index];
}
int size()
{
return m_size;
}
};
template <typename Item>
class Array
{
private:
Item *m_data;//指向首元素的指针
int m_size;//当前元素个数
int m_capacity;//能容纳元素的容量
public:
Array(int capacity)
{
m_capacity = (capacity >0) ? capacity:10;
m_data = new Item[m_capacity] {};
}
~Array()
{
if (m_data == NULL) return;
delete[] m_data;
}
void add(int value)
{
if (m_size == m_capacity)
{
int *tmp = m_data;
int *m_data = new int[m_capacity + 1];
for (int i = 0; i <= m_size; i++) {
*(m_data +i) = *(tmp+i);
}
delete[] tmp;
}
m_data[m_size++] = value;
}
int get(int index)
{
if (index < 0 || index >= m_size) {
cout << "越界" << endl;
return -1;
};
return m_data[index];
}
int size()
{
return m_size;
}
};
使用类模板时候,如果函数实现和声明分离,则每一个函数实现都要带上函数模板声明,并指明类型参数
template <typename Item>
int Array<Item>::get(int index)
{
if (index < 0 || index >= m_size) {
cout << "越界" << endl;
return -1;
};
return m_data[index];
}