1.使用类模板创建数组
下面这段代码:是创建一个元素为 T 类型的数组。
1 #pragma once 2 3 template<class T> 4 class MyArray 5 { 6 public: 7 //有参构造 8 MyArray(int capacity) 9 { 10 mCapacity = capacity; 11 mSize = 0; 12 pAdress = new T[mCapacity]; 13 } 14 //拷贝构造 15 MyArray(const MyArray& my1) 16 { 17 this->mCapacity = my1.mCapacity; 18 this->mSize = my1.mSize; 19 this->pAdress = new T[mCapacity]; 20 for (int i = 0; i < mSize; i++) 21 pAdress[i] = my1.pAdress[i]; 22 } 23 //重载等号操作符 24 MyArray& operator=(const MyArray& my1) 25 { 26 if (this->pAdress != NULL) 27 { 28 delete[] pAdress; 29 this->pAdress = NULL; 30 } 31 this->mCapacity = my1.mCapacity; 32 this->mSize = my1.mSize; 33 this->pAdress = new T[mCapacity]; 34 for (int i = 0; i < mSize; i++) 35 pAdress[i] = my1.pAdress[i]; 36 return *this; 37 } 38 //重载[]号操作符 39 T& operator[](int index) 40 { 41 return this->pAdress[index]; 42 } 43 44 //尾插法 45 void pushBack(T val) 46 { 47 if (mSize == mCapacity) 48 return; 49 pAdress[mSize] = val; 50 mSize++; 51 } 52 //尾部删除法 53 void popBack() 54 { 55 mSize--; 56 } 57 ~MyArray() 58 { 59 if (this->pAdress) 60 { 61 delete[] pAdress; 62 pAdress = NULL; 63 mCapacity = 0; 64 mSize = 0; 65 } 66 } 67 68 69 private: 70 T* pAdress; //指向数组的指针 71 int mCapacity; 72 int mSize; 73 };
2.下面这段代码:是利用上面的模板创建了两个数组(一个是基本数据类型,一个是自定义的类型)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 using namespace std; 4 #include"MyArray.hpp" 5 6 //普通类型 7 void test021() 8 { 9 MyArray<char> arr(10); 10 for (char i = 'a'; i <= 'j'; i++) 11 arr.pushBack(i); 12 for (int i = 0; i < 10; i++) 13 cout << arr[i]<<" "; 14 } 15 16 //自定义类型 17 class person 18 { 19 public: 20 //无参构造 21 person() 22 { 23 this->mName = new char[strlen("undefined!") + 1]; 24 strcpy(this->mName, "undefined!"); 25 mAge = -1; 26 } 27 //有参构造 28 person(char *name, int age) 29 { 30 mName = new char[strlen(name) + 1]; 31 strcpy(mName, name); 32 mAge = age; 33 } 34 //拷贝构造 35 person(const person& p1) 36 { 37 mName = new char[strlen(p1.mName) + 1]; 38 strcpy(mName, p1.mName); 39 mAge = p1.mAge; 40 } 41 42 //重载等号操作符 43 person& operator=(const person& p1) 44 { 45 if (mName != NULL) 46 { 47 delete[] mName; 48 mName = NULL; 49 } 50 mName = new char[strlen(p1.mName) + 1]; 51 strcpy(mName, p1.mName); 52 mAge = p1.mAge; 53 return *this; 54 } 55 //对 mName的赋值函数 56 void sendName(const char * ch) 57 { 58 if (mName) 59 { 60 delete[] mName; 61 mName = NULL; 62 } 63 mName = new char[strlen(ch) + 1]; 64 strcpy(mName, ch); 65 } 66 //析构函数 67 ~person() 68 { 69 if (mName) 70 { 71 cout << "析构函数" << endl; 72 delete[] mName; 73 mName = NULL; 74 } 75 } 76 public: 77 char *mName; 78 int mAge; 79 }; 80 81 //自定义类型 82 void test022() 83 { 84 //自定义类型必须提供默认构造函数 85 MyArray<person> arr(10); 86 /*for (int i = 0; i < 10; i++) //当初写这段代码时,与下面代码的区别是没有 sendName() 这个函数。此时采用这种赋值方式有两个隐患 87 { //1.因为自定义的类中有无参构造函数,对对象的每个变量进行了赋值。由于其中一个变量是指针,那么此时它就具有了空间指向。 88 sprintf(arr[i].mName, "%d%dasafqwdqwdqwdsa%d%d", i, i, i + 1, i + 1); //2.这时直接赋值是对对象的初始化内容进行替换,并没有申请新内存,而此时对象的指针由于经过初始化,具有了 89 arr[i].mAge = i + 10; //固定大小的内存,一旦赋值超出其长度,就会造成内存泄漏。只有当赋值的内存小于初始化长度时,才不会造成错误。 90 }*/ 91 for (int i = 0; i < 10; i++) 92 { //这段代码是上段代码的加强版,有了sendName()这个函数,它具有两个功能, 93 char buf[100]; //1.它把对象指针原来指向的内存空间先释放了, 94 sprintf(buf, "%d%dasafqwdqwdqwdsa%d%d", i, i, i + 1, i + 1); //2.然后再重新申请赋值长度大小的内存,给他进行了赋值。 95 arr[i].sendName(buf); //3.由于sprintf()函数的特点,这里得创建一个缓存空间,足够大,将赋值的内容先拷贝进去,然后再把这个内存空间传入sendName()函数。 96 arr[i].mAge = i + 10; 97 } 98 //这两段代码最主要的区别是: 99 1.第一段赋值代码没有进行原内存的释放,但同时也没有申请新内存,一旦赋值的长度超过其初始化 mName 的内存,就造成了内存泄漏。 100 2.第二段赋值代码增加了一个赋值函数,这个函数具有两个功能,(1)释放 mName 原有的内存,(2)对 mName 进行新内存的动态申请。 101 3.由于这个函数所传参数的限制,以及 sprintf()函数的使用特点,只有设置一个足够大的缓冲内存,将赋值的内容先拷贝进缓冲内存, 102 再把缓冲内存做实参传给赋值函数,实现对 mName 的赋值。 103 /*person p1("john1", 19); 104 person p2("john2", 29); 105 person p3("john3", 39); 106 person p4("john4", 49); 107 person p5("john5", 59); 108 arr[1] = p1; 109 arr.pushBack(p2); 110 cout << "Name:" << arr[0].mName << " Age:" << arr[0].mAge << endl; 111 arr.pushBack(p3); 112 cout << "Name:" << arr[1].mName << " Age:" << arr[1].mAge << endl;*/ 113 114 for (int i = 0; i < 10; i++) 115 cout << "Name:" << arr[i].mName << " Age:" << arr[i].mAge << endl; 116 } 117 118 int main() 119 { 120 test022(); 121 test021(); 122 123 system("pause"); 124 return EXIT_SUCCESS; 125 }