zoukankan      html  css  js  c++  java
  • C++的泛型编程方式

    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 }
  • 相关阅读:
    文件操作
    join,列表和字典用for循环的删除,集合,深浅拷贝
    java多线程基础
    nginx应用及性能调优
    nginx 基本功能
    SpringBoot2.x 启动过程详解
    shell脚本的基本使用
    使用 maven 的 `wagon-maven-plugin`插件 快速部署 到不同的 环境
    Netty笔记(7)
    Netty笔记(6)
  • 原文地址:https://www.cnblogs.com/yyx1-1/p/5731158.html
Copyright © 2011-2022 走看看