首先创建一个类的.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. }
在向容器中装入自己定义的类对象时,一定要自己实现拷贝构造函数,否则可能出现浅拷贝的问题。