0%

C++ - 类模板

最近在学习 C++,所以顺便将每日所学记录下来,一方面为了巩固学习的知识,另一方面也为同样在学习C++的童鞋们提供一份参考。

类模板

所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。

基础

重载函数类模板

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
38
39
40
41
42
43
44
45

#include <iostream>
using namespace std;

template <typename T> //类模板创建
class A
{
public:

T GetA()
{
cout << "a = " << a << endl;
return a;
}
T SetA(T a)
{
this->a = a;
return this->a;
}
private:
T a;
};


void Print(A<int> *A1) //重载Print函数
{
A1->SetA(10);
A1->GetA();
}

void Print(A<char> *A1)
{
A1->SetA('a');
A1->GetA();
}

int main()
{
A<int> A1;
A<char> A2;
Print(&A1);
Print(&A2);
system("pause");
return 0;
}

继承模板类

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
using namespace std;
template <typename T> //类模板创建
class A
{
public:
~A()
{
;
};

A(int a)
{
this->a = a;
}

T GetA()
{
cout << "a = " << a << endl;
return a;
}
T SetA(T a)
{
this->a = a;
return this->a;
}
private:
T a;
};

class B : protected A<int>
{

};

class C : public A<int>
{
public:
C(int a, int b) :A<int>(a) //参数列表
{
this->a = a;
this->b = b;
}
private:
int a, b;
};


void Print(A<int> *a)
{
a->GetA();
}

int main()
{
C c1(1000, 2000);
c1.GetA();
Print(&c1);
system("pause");
return 0;
}

类模板友元函数

在类模板中可以声明各种友元关系

  • 一个函数或函数模板可以是类或类模板的友元
  • 一个类或模板可以是类或类模板的友元类
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
using namespace std;

template <class T>
class Complex
{
public:
Complex(T Real = 0, T Image = 0);
Complex(T a);
friend Complex operator+(Complex &c1, Complex &c2); //友元函数
friend Complex operator-(Complex &c1, Complex &c2)
{
Complex temp(c1.Real - c2.Real, c2.Image - c2.Image);
return temp;
};
/*public:

*/
Complex();
~Complex();
void Print();
private:
T Real;
T Image;
};
template <class T>
Complex<T>::Complex(T Real, T Image)
{
this->Real = Real;
this->Image = Image;
}

template <class T>
Complex<T>::Complex(T a)
{
this->Real = a;
this->Image = 0;
}

template<class T>
Complex<T>::~Complex()
{
;
}

template <class T>
Complex<T> ::Complex()
{
cout << this->Image << " " << this->Real << endl;
}

template <class T>
void Complex<T> ::Print()
{
cout << this->Image << " " << this->Real << endl;
}

template <class T>
Complex<T> operator+(Complex<T> &c1, Complex<T> &c2)
{
Complex<T> temp(c1.Real + c2.Real, c1.Image + c2.Image);

return temp;
}




int main()
{
Complex<float> c1(1.0, 2.0);
Complex<float> c2(3.0, 4.0);

Complex<float> c3 = c1 - c2;
c3.Print();
Complex<float> c4 = c1 + c2;
c4.Print();
system("pause");
return 0;
}

类模板与static成员

  • 从类模板实例化的每个模板类有自己的类模板成员函数,该模板类的所有对象共享一个static数据成员
  • 和非模板类的static数据成员一样,模板类的static数据成员也应该在文件范围定义和初始化
  • 每个模板类有自己的类模板行和static数据成员副本
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
38
39
40
41
42
43

#include <iostream>
using namespace std;

template <typename T>
class A
{
public:
static int m_a;
private:
T a1;
};

template <typename T>
int A<T>::m_a = 0;

void Print(A<int> *a)
{
cout << a->m_a << endl;
}

void Print(A<float> *a)
{
cout << a->m_a << endl;
}

int main()
{
A<int> a1;
A<int> a2;
A<int> a3;

A<float> b1;
A<float> b2;
A<float> b3;

a1.m_a++;
b3.m_a = 100;
Print(&a1);
Print(&b3);
system("pause");
return 0;
}

总结

  • 模板是C++类型参数化的多态工具
  • 模板定义以模板说明开始。类属性参数必须在模板定义中至少出现一次;
  • 同一个类属性参数可以用于多个模板;
  • 类属参数可以用于函数的参数类型、返回类型和声明函数中的变量;
  • 模板由编译器根据实际数据类型实例化;
  • 函数模板可以用多种方式重载;
  • 类模板可以在类层次中使用;