【泛型编程】类模板实现简单的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. }

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


相关文章
|
25天前
|
设计模式 程序员 C++
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
241 2
|
25天前
|
存储 安全 编译器
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
47 1
|
25天前
|
存储 安全 算法
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
47 1
|
1月前
|
存储 网络协议 C++
C++ Vector容器详解:一站式指南,掌握动态数组的高效使用
C++ Vector容器详解:一站式指南,掌握动态数组的高效使用
49 2
|
1月前
|
存储 缓存 安全
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
15 0
|
存储 编译器 程序员
【C++】容器篇(一)—— vector 的基本概述以及模拟实现
【C++】容器篇(一)—— vector 的基本概述以及模拟实现
|
1月前
|
小程序 前端开发 定位技术
【微信小程序】-- 常用视图容器类组件介绍 -- view、scroll-view和swiper(六)
【微信小程序】-- 常用视图容器类组件介绍 -- view、scroll-view和swiper(六)
|
1月前
|
安全 Java API
Java并发 - J.U.C并发容器类 list、set、queue
Queue API 阻塞是通过 condition 来实现的,可参考 Java 并发 - Lock 接口 ArrayBlockingQueue 阻塞 LinkedBlockingQueue 阻塞 ArrayQueue 非阻塞 LinkedQueue 非阻塞
|
1月前
|
存储 安全 C++
深入理解C++ STL中的vector容器
深入理解C++ STL中的vector容器
12 0
|
1天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
7 0