【泛型编程】类模板实现简单的vector容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 【泛型编程】类模板实现简单的vector容器

首先创建一个类的.h和.cpp文件,分别如下

UserVector.h文件

1. #pragma once //只包含一次
2. 
3. #include <iostream>
4. using namespace std;
5. 
6. template<typename user_t>
7. class UserVector
8. {
9. public:
10.   //构造函数与析构函数
11.   UserVector(int len = 0); //有了默认初始参数,不需要在写无参构造函数 UserVector();
12.   UserVector(UserVector<user_t>& v); //UserVector<user_t> 必须指明类型来告诉编译器如何分配内存
13.   ~UserVector();
14. public:
15.   //重载函数
16.   user_t& operator[](int index);
17.   friend ostream& operator<< <user_t> (ostream& out, UserVector<user_t>& u);
18.   UserVector<user_t>& operator=(UserVector<user_t>& u);
19. private:
20.   int   len;
21.   user_t* p;
22. };

其中

#pragma once

表示只包含一次该头文件,防止重复包含导致的重定义,相当于C语言中的

1. #ifndef _USER_VECTOR_H
2. #define _USER_VECTOR_H
3. 
4. /*
5. 程序代码
6. */
7. 
8. #endif

UserVector.cpp文件

1. #include "UserVector.h"
2. 
3. template<typename user_t>
4. UserVector<user_t>::UserVector(int len)
5. {
6.  this->len = len;
7.  this->p = new user_t[this->len];
8. }
9. 
10. template<typename user_t>
11. UserVector<user_t>::UserVector(UserVector<user_t>& v)
12. {
13.   this->len = v.len;
14.   this->p = new user_t[this->len];
15.   for (int i = 0; i < this->len; i++)
16.   {
17.     this->p[i] = v.p[i];
18.   }
19. }
20. 
21. template<typename user_t>
22. UserVector<user_t>::~UserVector()
23. {
24.   if (this->p != NULL)
25.   {
26.     delete[] this->p;
27.   }
28.   this->p = NULL;
29.   this->len = 0;
30. }
31. 
32. template<typename user_t>
33. user_t& UserVector<user_t>::operator[](int index)
34. {
35.   return this->p[index];
36. }
37. 
38. template<typename user_t>
39. //std::ostream& operator<< <user_t> (std::ostream& out, UserVector<user_t>& u)
40. //错误  C2768 “operator << ”: 非法使用显式模板参数  
41. std::ostream& operator<<(std::ostream& out, UserVector<user_t>& u)
42. {
43.   for (int i = 0; i < u.len; i++)
44.   {
45.     out << u.p[i] << " ";
46.   }
47.   return out;
48. }
49. 
50. template<typename user_t>
51. UserVector<user_t>& UserVector<user_t>::operator=(UserVector<user_t>& u)
52. {
53.   if (this->p != NULL)
54.   {
55.     delete[] this->p;
56.     //无需置NULL,因为下面立马要修改
57.   }
58. 
59.   this->len = u.len;
60.   this->p = new user_t[this->len];
61. 
62.   for (int i = 0; i < this->len; i++)
63.   {
64.     this->p[i] = u.p[i];
65.   }
66. 
67.   return *this;
68. }

这里注意,在类模板中重载运算符的时候一定不能乱用友元函数,一般只有重载左移右移运算符时,才能使用友元函数,否则会报各种错误,并且在重载左移右移运算符的时候,函数声明一定要这样声明

friend ostream& operator<< <user_t> (ostream& out, UserVector<user_t>& u);

主测试函数函数如下

1. #define _CRT_SECURE_NO_WARNINGS
2. 
3. #include <iostream>
4. using namespace std;
5. 
6. //#include "UserVector.h" //报一堆错
7. #include "UserVector.cpp"
8. 
9. void FuncTest1()
10. {
11.   //1. int 类型的容器
12.   UserVector<int> i1(10);
13.   for (int i = 0; i < 10; i++)
14.   {
15.     i1[i] = i;
16.   }
17.   cout << "i1: " << i1 << endl;
18. 
19.   UserVector<int> i2 = i1;
20.   cout << "i2: " << i2 << endl;
21. 
22.   UserVector<int> i3;
23.   i3 = i2;
24.   cout << "i3: " << i3 << endl;
25. 
26.   //2. char
27.   UserVector<char> c1(3);
28.   c1[0] = 'a';
29.   c1[1] = 'b';
30.   c1[2] = 'c';
31.   cout << "c1: " << c1 << endl;
32. 
33.   UserVector<char> c2;
34.   c2 = c1;
35.   cout << "c2: " << c2 << endl;
36. }
37. 
38. class People
39. {
40. public:
41.   People()
42.   {
43.     this->age = 0;
44.     this->name = NULL;
45.   }
46.   People(int age, const char* p) //装入容器时,必须要有拷贝构造函数
47.   {
48.     this->age = age;
49.     this->name = new char[strlen(p) + 1];
50.     strcpy(this->name, p);
51.   }
52.   People(People& p)
53.   {
54.     this->age = p.age;
55.     this->name = new char[strlen(p.name) + 1];
56.     strcpy(this->name, p.name);
57.   }
58.   ~People()
59.   {
60.     if (this->name != NULL)
61.     {
62.       delete[] this->name;
63.     }
64.     this->name = NULL;
65.     this->age = 0;
66.   }
67. public:
68.   People& operator=(People& p)
69.   {
70.     if (this->name != NULL)
71.     {
72.       delete[] this->name;
73.     }
74. 
75.     this->name = new char[strlen(p.name) + 1];
76.     this->age = p.age;
77.     strcpy(this->name, p.name);
78. 
79.     return *this;
80.   }
81.   friend ostream& operator<<(ostream& out, People& p)
82.   {
83.     out << p.name << ": " << p.age << endl;
84.     return out;
85.   }
86. private:
87.   int   age;
88.   char* name;
89. };
90. 
91. void FuncTest2()
92. {
93.   People p1(16, "p1"), p2(17, "p2"), p3(18, "p3");
94.   UserVector<People> V(3);
95.   V[0] = p1;
96.   V[1] = p2;
97.   V[2] = p3;
98. 
99.   cout << V[0] << V[1] << V[2] << endl;
100. }
101. 
102. int main()
103. {
104.  //装入普通类型
105.  FuncTest1();
106. 
107.  //装入 类对象
108.  FuncTest2();
109. 
110.  system("pause");
111.  return 0;
112. }

在向容器中装入自己定义的类对象时,一定要自己实现拷贝构造函数,否则可能出现浅拷贝的问题。


相关文章
|
4月前
|
存储 C++ 容器
如何将没有复制或移动构造函数的对象放入vector容器
如何将没有复制或移动构造函数的对象放入vector容器
42 0
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
53 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
2月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
55 5
|
4月前
|
存储 Kubernetes Cloud Native
探索Python编程的奥秘云原生时代的容器编排:Kubernetes入门与实践
【8月更文挑战第30天】本文以浅显易懂的方式,探讨了Python编程的核心概念和技巧。从基础语法到高级特性,再到实际应用案例,逐步引导读者深入理解Python编程的精髓。通过本文的学习,读者将能够掌握Python编程的基本技能,并激发进一步探索的兴趣。
42 13
|
4月前
|
安全 算法 Java
【Java集合类面试二】、 Java中的容器,线程安全和线程不安全的分别有哪些?
这篇文章讨论了Java集合类的线程安全性,列举了线程不安全的集合类(如HashSet、ArrayList、HashMap)和线程安全的集合类(如Vector、Hashtable),同时介绍了Java 5之后提供的java.util.concurrent包中的高效并发集合类,如ConcurrentHashMap和CopyOnWriteArrayList。
【Java集合类面试二】、 Java中的容器,线程安全和线程不安全的分别有哪些?
|
4月前
|
容器
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Group Box的使用及说明
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Group Box的使用及说明
294 3
|
4月前
|
容器
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Tab Widget的使用及说明
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Tab Widget的使用及说明
146 2
|
4月前
|
数据采集 监控 Kubernetes
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
|
4月前
|
数据采集 Kubernetes Java
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
|
4月前
|
存储 Kubernetes 数据处理
Job类日志采集问题之为什么Job容器的日志采集要考虑容器发现速度和开始采集延时,如何理解
Job类日志采集问题之为什么Job容器的日志采集要考虑容器发现速度和开始采集延时,如何理解