目录
一、函数模板
1、函数模板的概念
2、函数模板的语法
3、模板函数调用方式
4、函数模板的使用
二、类模板
1、类模板的概念
2、类模板的语法
3、类模板的使用
4、模板的继承
5、模板中关于函数的声明
6、模板中的static
练习:改错
一、函数模板
1、函数模板的概念
概念:c++提供的函数模板机制,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来表示,这个通用的函数称为模板函数
2、函数模板的语法
格式:
template<类型形式参数表>
类型 函数名(形式参数表)
{
代码块
}
//当模板函数和普通函数同时存在,优先调用普通函数
3、模板函数调用方式
(1)隐式调用
//不写入的参数类型,让编译器自己判断传入的是什么类型的数据
//模板函数不能自动发生隐式类型转换
int n1 = 100, n2 = 200;
Swap(n1, n2); //隐式调用
(2)显示调用
格式:
函数名<类型列表> (实参列表)
//在调用时说明传入的类型参数
Swap(c1, c2); //显示调用
4、函数模板的使用
#include
using namespace std;
template //声明虚拟类型T,作用范围到这个函数结束
T add(T x, T y)
{
return x + y;
}
template
void print(T1 x,T2 y)
{
cout<(1.11,97);
return 0;
}
二、类模板
1、类模板的概念
格式:
template<类型形式参数表>
类型 函数名(形式参数表)
{
代码块
}
//当模板函数和普通函数同时存在,优先调用普通函数
(1)隐式调用
//不写入的参数类型,让编译器自己判断传入的是什么类型的数据
//模板函数不能自动发生隐式类型转换
int n1 = 100, n2 = 200;
Swap(n1, n2); //隐式调用
(2)显示调用
格式:
函数名<类型列表> (实参列表)
//在调用时说明传入的类型参数
Swap
(c1, c2); //显示调用
4、函数模板的使用
#include
using namespace std;
template //声明虚拟类型T,作用范围到这个函数结束
T add(T x, T y)
{
return x + y;
}
template
void print(T1 x,T2 y)
{
cout<(1.11,97);
return 0;
}
二、类模板
1、类模板的概念
1、类模板的概念
类模板中定义的函数类型可以用在类声明和类实现中,类模板的目的是将数据的类型参数化。
2、类模板的语法
template
class 类型{
.......
}
//类模板创建对象一定要显示调用
3、类模板的使用
#include
using namespace std;
template
class Test
{
private:
T a;
U b;
public:
Test(T a, U b)
{
this->a = a;
this->b = b;
}
void show()
{
cout< t(1,'a'); //类模板创建对象一定要显示调用
t.show();
return 0;
}
4、模板的继承
//模板类派生普通类,继承的同时对基类进行实列化(指明基类的具体类型)
//模板类派生模板类,继承时可以不需要对基类进行实列化(基类类型可以不指明)
#include
using namespace std;
template
class Parent
{
protected:
T a;
public:
Parent(T a)
{
this->a = a;
}
void show()
{
cout<<"a = "< //模板类派生普通类,继承的同时对基类实例化
{
public:
Child(int a):Parent(a) //构造函数同样需要实例化
{
}
void show()
{
cout<<"a = "<
class Child2:public Parent //模板类派生模板类,继承的同时不需要对parent实例化
{
private:
U b;
public:
Child2(F a,U b):Parent(a)
{
this->b = b;
}
void show()
{
cout<a<<" "< c2(1,2.222);
c2.show();
return 0;
}
5、模板中关于函数的声明
template
class 类型{
.......
}
//类模板创建对象一定要显示调用
#includeusing namespace std; template class Test { private: T a; U b; public: Test(T a, U b) { this->a = a; this->b = b; } void show() { cout< t(1,'a'); //类模板创建对象一定要显示调用 t.show(); return 0; }
4、模板的继承
//模板类派生普通类,继承的同时对基类进行实列化(指明基类的具体类型)
//模板类派生模板类,继承时可以不需要对基类进行实列化(基类类型可以不指明)
#include
using namespace std;
template
class Parent
{
protected:
T a;
public:
Parent(T a)
{
this->a = a;
}
void show()
{
cout<<"a = "< //模板类派生普通类,继承的同时对基类实例化
{
public:
Child(int a):Parent(a) //构造函数同样需要实例化
{
}
void show()
{
cout<<"a = "<
class Child2:public Parent //模板类派生模板类,继承的同时不需要对parent实例化
{
private:
U b;
public:
Child2(F a,U b):Parent(a)
{
this->b = b;
}
void show()
{
cout<a<<" "< c2(1,2.222);
c2.show();
return 0;
}
5、模板中关于函数的声明
//模板类派生普通类,继承的同时对基类进行实列化(指明基类的具体类型)
//模板类派生模板类,继承时可以不需要对基类进行实列化(基类类型可以不指明)
//函数在类外部时,需要重写模板
#includeusing namespace std; template class Test { private: T a; U b; public: Test(T a, U b); void show(); }; template Test ::Test(T a, U b) { this->a = a; this->b = b; } template void Test ::show() { cout< t(1,'a'); //类模板创建对象一定要显示调用 t.show(); return 0; }
6、模板中的static
//类中的 static 修饰的变量,需要在类外部进行初始化
//成员变量在初始化之前,需要重写模板
//static 修饰的成员变量,按模板进行分配,换句话说,相同的模板,用的是同一个static 成员变量
#include
using namespace std;
template
class Test
{
private:
T a;
U b;
public:
static int count;
public:
Test(T a, U b);
void show();
};
template
int Test::count = 0;
template
Test::Test(T a, U b)
{
this->a = a;
this->b = b;
count++;
}
template
void Test::show()
{
cout< t1(1,'a');
Test t2(1,'a');
Test t3(1,'a');
Test t4(1,'a');
Test t5(1,'a');
Test t6(1,1.11);
Test t7(2,1.11);
Test t8(3,1.11);
cout<::count<::count<
练习:改错
#include
struct test{
int a;
int b;
};
void func(struct test *tt)
{
struct test *lt;
lt = &tt[0];
printf("[0] a : %d,b:%dn",lt->a,lt->b);
lt = &tt[1];
printf("[1] a : %d,b:%dn",lt->a,lt->b);
lt = &tt[2];
printf("[2] a : %d,b:%dn",lt->a,lt->b);
return;
};
int main(int argc, char const *argv[])
{
struct test lm[3] = {{1,2},{11,22},{111,222}};
struct test llm = {333,444};
func(lm);
func(&llm);
return 0;
}
上述代码,错误在于数组作为函数传参时,需要传两个方面的值:数组首地址、数组大小;
//类中的 static 修饰的变量,需要在类外部进行初始化
//成员变量在初始化之前,需要重写模板
//static 修饰的成员变量,按模板进行分配,换句话说,相同的模板,用的是同一个static 成员变量
练习:改错
#include
struct test{
int a;
int b;
};
void func(struct test *tt)
{
struct test *lt;
lt = &tt[0];
printf("[0] a : %d,b:%dn",lt->a,lt->b);
lt = &tt[1];
printf("[1] a : %d,b:%dn",lt->a,lt->b);
lt = &tt[2];
printf("[2] a : %d,b:%dn",lt->a,lt->b);
return;
};
int main(int argc, char const *argv[])
{
struct test lm[3] = {{1,2},{11,22},{111,222}};
struct test llm = {333,444};
func(lm);
func(&llm);
return 0;
}
上述代码,错误在于数组作为函数传参时,需要传两个方面的值:数组首地址、数组大小;
上述代码,错误在于数组作为函数传参时,需要传两个方面的值:数组首地址、数组大小;



