模板
发表于:2024-12-19 | 分类: C++
字数统计: 1k | 阅读时长: 5分钟 | 阅读量:

模版

函数模版

语法

  • 使用template关键字

  • T可以代表任意类型,字符使用啥都行,不一定是T

  • 编译器在调用模板时,会根据传入的参数类型自动生成对应的函数实例。

1
2
3
4
template <typename T>
T add(T a, T b){
return a+b;
}

支持多参数T,一般用一个就行

1
template <typename T,typename A,...>

案例

用函数模版实现方法重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

// 定义单参数函数模版
template <typename T>
T add(T a, T b)
{
return a + b;
}

// 定义多参数函数模版
template <typename T, typename U>
T sub(T a, U b)
{
return a - b;
}

int main()
{
// 调用单参数函数模版
cout << "add(1,2)=" << add(1, 2) << endl;
cout << "add(1.1,2.2)=" << add(1.1, 2.2) << endl;

// 调用多参数函数模版
cout << "sub(1,2)=" << sub(1, 2) << endl;
cout << "sub(1.1,2.2)=" << sub(1.1, 2.2) << endl;
return 0;
}

类模版

类模板用于定义可以处理任意类型的类,是 STL 容器(如 vectorlist)实现的基础。

语法

  • 还是使用template,对类属性的类型使用
  • 注意:模版类的声明和定义不能分离(写在同一个文件中)
  • 所有方法都需要加上模板类的函数定义,如template <typename T, typename U>
1
2
3
4
5
6
7
8
9
// template <typename T = int> ,也可以这样写,默认int
template <typename T>
class MyClass
{
public:
T data;
MyClass(T value);
void show();
};

使用时,指定模版的类型,如MyClass<int> obj(3);

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef STUDENT_H_
#define STUDENT_H_

template <typename T, typename U>
class MyClass
{
public:
T data;
MyClass(T value);
T getData();
U setData(T value);
void show();
};

// 所有方法都需要加上模板类的函数定义
template <typename T, typename U>
MyClass<T, U>::MyClass(T value) : data(value) {}

template <typename T, typename U>
T MyClass<T, U>::getData()
{
return data;
}

template <typename T, typename U>
U MyClass<T, U>::setData(T value)
{
data = value;
return data;
}

template <typename T, typename U>
void MyClass<T, U>::show()
{
std::cout << "Data: " << data << std::endl;
}
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include "myclass.h"
using namespace std;

int main()
{
MyClass<int, int> obj1(5);
obj1.show();
obj1.setData(10);
obj1.show();

cout << "-------------------" << endl;

MyClass<int, double> obj2(10);
obj2.show();
obj2.setData(5);
obj2.show();
return 0;
}

模版类继承

基类

  • 下方是vector类的部分定义,包含类型<Tp,Tp>
  • allocator表示是默认的,子类不继承也可以,即<Tp>也行(推荐)
1
2
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>

继承

  • 完全模版继承:派生类(需要定义为模版类)全部继承,继承<Tp,Tp>(或者<Tp>,如果有allocator)

  • 部分模版继承:派生类(需要定义为模版类)指定部分类型,如<Tp,int>,

  • 非模版继承:指定具体类型,如,不需要定义为模版类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef VECTOR_S_H
#define VECTOR_S_H

#include <vector>
#include <iostream>

// 模板类 VectorS,支持任意类型 T
template <typename T>
class VectorS : public std::vector<T>
{
public:
T getElement(int index);
};

template <typename T>
T VectorS<T>::getElement(int index)
{
if (this->size() > index)
{
// (*this)即Vectors对象
return (*this)[index];
}
else
{
std::cout << "Index out of range" << std::endl;
// 返回T类型的默认值
return T();
}
}

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include "vector_s.h"

using namespace std;

int main()
{
VectorS<int> v;
v.push_back(1);
v.push_back(2);
cout << v.getElement(0) << endl;
cout << v.getElement(1) << endl;
cout << v.getElement(2) << endl; // 越界

cout << "-------------------" << endl;

VectorS<string> v1;
v1.push_back("c++");
v1.push_back("C#");
cout << v1.getElement(0) << endl;
cout << v1.getElement(1) << endl;
cout << v1.getElement(2) << endl; // 越界
return 0;
}
上一篇:
Linux VS Code 图形转发
下一篇:
抽象类