zoukankan      html  css  js  c++  java
  • 数组类的创建(下)

    创建StaticArray时,数组的大小必须是明确指定的,是一种限制。
    全新的数组类:DynamicArray使用时其对象代表的数组的大小能够动态的指定
    1、DynamicArray设计要点
    • 类模板
    • (任意时刻)动态确定内部数组空间大小  即存储数组的空间可以动态的指定
    • 实现函数返回数组长度
    • 拷贝构造和赋值操作
    2、DynamicArray类的声明

    3、DynamicArray实现
    DynamicArray.h
     
      1 #ifndef DYNAMICARRAY_H
      2 #define DYNAMICARRAY_H
      3 #include "array.h"
      4 
      5 namespace   DataStructureLib
      6 {
      7 template <typename T>
      8 class DynamicArray:public Array<T>
      9 {
     10 protected:
     11     int m_length;
     12 public:
     13     DynamicArray(int length)
     14     {
     15         m_array=new T[length];
     16         if(m_array!=NULL)
     17         {
     18              m_length=length;
     19         }
     20        else
     21         {
     22             THROW_EXCEPTION(NotEnoughMemoryException,"No Enough Memory to Create DynamicArray...");
     23         }
     24     }
     25 
     26     DynamicArray(const DynamicArray<T>&  obj)
     27     {
     28         m_array=new T[obj.length()];
     29         if(m_array!=NULL)
     30         {
     31 
     32              for(int i=0;i<obj.length();i++)
     33              {
     34                   this->m_array[i]=obj.m_array[i];
     35              }
     36              m_length=obj.length();
     37         }
     38        else
     39         {
     40             THROW_EXCEPTION(NotEnoughMemoryException,"No Enough Memory to Create DynamicArray...");
     41         }
     42     }
     43 
     44     DynamicArray& operator =(DynamicArray & obj)
     45     {
     46         //delete m_array [];
     47         //这里不能先delete[] this->m_array,再
     48         //赋值,因为delete可能会引起T调用析构函数,而如果在析构函数中抛出异常,以下对
     49         //成员变量的赋值都将无法进行,从而造成函数异常时的不安全。因此,正确的顺序应该是
     50         //先对成员变量赋值,最后再释放m_array的旧空间。
     51 
     52          if(this!=&obj)
     53          {
     54              //1. 分配新内存
     55              T* array=new T[obj.length()];
     56              //2. 拷贝数组的
     57              for(int i=0;i<obj.length();i++)
     58              {
     59                  array[i]=obj[i];
     60              }
     61               //3. 设置变量
     62              T* temp=this->m_array;//先设置参数,再删除m_array,以确保异常安全
     63 
     64              this->m_length=obj.length();
     65              m_array=array;
     66 
     67              delete    []temp;
     68          }
     69 
     70         return *this;
     71     }
     72 
     73     int length() const
     74     {
     75         return m_length;
     76     }
     77 
     78     void resize(int length)
     79     {
     80         if(m_length!=length)
     81         {
     82             int size=(m_length<length)?m_length:length;
     83 
     84             T* array=new T[size];
     85 
     86             if(array!=NULL)
     87             {
     88                 for(int i=0;i<size;i++)
     89                 {
     90                     array[i]=m_array[i];
     91                 }
     92 
     93                 T* temp=m_array;
     94 
     95                 m_array=array;
     96                 m_length=length;
     97 
     98                 delete []temp;
     99             }
    100             else
    101             {
    102                 THROW_EXCEPTION(NotEnoughMemoryException, "Not enough memory to resize Object ....");
    103             }
    104 
    105 
    106         }
    107     }
    108 
    109     ~DynamicArray()
    110     {
    111         delete []m_array;
    112     }
    113 };
    114 }
    115 #endif // DYNAMICARRAY_H

     main.cpp

     1 #include <iostream>
     2 #include "Exception.h"
     3 #include "dynamicarray.h"
     4 
     5 using namespace std;
     6 using namespace DTLib;
     7 
     8 int main()
     9 {
    10    DynamicArray<int> d(5);
    11 
    12    for(int i=0;i<d.length();i++)
    13    {
    14        d[i]=i*i;
    15    }
    16 
    17 
    18    for(int i=0;i<d.length();i++)
    19    {
    20        cout<<d[i]<<endl;
    21    }
    22 
    23    d.resize(5);
    24 
    25    for(int i=0;i<d.length();i++)
    26    {
    27        cout<<d[i]<<endl;
    28    }
    29 
    30     DynamicArray<int> d2(10);
    31 
    32     d2=d;
    33 
    34     for(int i=0;i<d2.length();i++)
    35     {
    36         cout<<d2[i]<<endl;
    37     }
    38 
    39    return 0;
    40 }

    3. DynamicArray类的问题与重构

    (1)逻辑问题:

      ①函数实现存在重复的逻辑(如赋值与resize函数)

      ②从逻辑看,代码可分解出更细的功能(如分配新内存、数组拷贝、设置新变量等)

    (2)代码优化

      ①init():对象构造时的初始化操作

      ②copy():在堆空间中申请新的内存,并执行拷贝操作

      ③update():将指定的堆空间设置为内部存储数组

    【编程实验】动态数组类的实现与重构

    #ifndef DYNAMICARRAY_H
    #define DYNAMICARRAY_H
    #include "array.h"
    
    namespace   DataStructureLib
    {
    template <typename T>
    class DynamicArray:public Array<T>
    {
    protected:
        int m_length;
    
       //分配内存并拷贝数组元素
        T* copy(T* array,int len,int newlen)
        {
            T*ret =new T[newlen];
    
           if(ret!=NULL)
          {
           int size=(len<newlen)?len:newlen;
               for(int i=0;i<size;i++)
              {
                ret[i]=array[i];
               }
            }
           return ret;
        }
    
         //将指定的堆空间设置为类中的成员
        void updata(T* array,int length)
        {
            if(array!=NULL)
            { //先设置变量,再删除。确保异常安全!
    
                T* temp=this->m_array;
    
                this->m_array=array;
                this->m_length=length;
    
                delete []temp;
            }
            else
            {
                THROW_EXCEPTION(NotEnoughMemoryException, "Not enough memory to update DynamicArray Object ....");
            }
    
        }
    
    
        //对象构造时的初始化操作
            void init(T* array,int length)
            {
                m_array=array;
                if(m_array!=NULL)
                {
                     m_length=length;
                }
               else
                {
                    THROW_EXCEPTION(NotEnoughMemoryException,"No Enough Memory to Create DynamicArray...");
                }
            }
    public:
        DynamicArray(int length)
        {
    //        m_array=new T[length];
    //        if(m_array!=NULL)
    //        {
    //             m_length=length;
    //        }
    //       else
    //        {
    //            THROW_EXCEPTION(NotEnoughMemoryException,"No Enough Memory to Create DynamicArray...");
    //        }
              init(new T[length],length );
    
        }
    
        DynamicArray(const DynamicArray<T>&  obj)
        {
    
    
            /////////////////////
    //        m_array=new T[obj.length()];
    //        if(m_array!=NULL)
    //        {
    
    //             for(int i=0;i<obj.length();i++)
    //             {
    //                  this->m_array[i]=obj.m_array[i];
    //             }
    //             m_length=obj.length();
    //        }
    //       else
    //        {
    //            THROW_EXCEPTION(NotEnoughMemoryException,"No Enough Memory to Create DynamicArray...");
    //        }
           T* array= copy(obj.m_array,obj.m_length,obj.m_length);
    
           init(array,obj.m_length);
        }
    
        DynamicArray& operator =(DynamicArray & obj)
        {
            //delete m_array [];
            //这里不能先delete[] this->m_array,再
            //赋值,因为delete可能会引起T调用析构函数,而如果在析构函数中抛出异常,以下对
            //成员变量的赋值都将无法进行,从而造成函数异常时的不安全。因此,正确的顺序应该是
            //先对成员变量赋值,最后再释放m_array的旧空间。
    
             if(this!=&obj)
             {
                 //1. 分配新内存
    //             T* array=new T[obj.length()];
                 //2. 拷贝数组的
    //             for(int i=0;i<obj.length();i++)
    //             {
    //                 array[i]=obj[i];
    //             }
                  //3. 设置变量
    //             T* temp=this->m_array;//先设置参数,再删除m_array,以确保异常安全
    
    //             this->m_length=obj.length();
    //             m_array=array;
    
    //             delete    []temp;
    
    
                 /***********重构后**************/
                 T* array=copy(obj,obj.length(),obj.length());
                 updata(array,obj.m_length);
             }
    
            return *this;
        }
    
        int length() const
        {
            return m_length;
        }
    
        void resize(int length)
        {
            if(m_length!=length)
            {
    //            int size=(m_length<length)?m_length:length;
    
    //            T* array=new T[size];
    
    //            if(array!=NULL)
    //            {
    //                for(int i=0;i<size;i++)
    //                {
    //                    array[i]=m_array[i];
    //                }
    
    //                T* temp=m_array;
    
    //                m_array=array;
    //                m_length=length;
    
    //                delete []temp;
    //            }
    //            else
    //            {
    //                THROW_EXCEPTION(NotEnoughMemoryException, "Not enough memory to resize Object ....");
    //            }
    
               T* array= copy(this->m_array,this->m_length,length);
               updata(array,length);
            }
        }
    
        ~DynamicArray()
        {
            delete []m_array;
        }
    };
    }
    #endif // DYNAMICARRAY_H
  • 相关阅读:
    反射
    IDEA配置数据库
    配置idea的maven镜像为aliyun
    蓝桥---芯片测试(思维)
    汉诺塔(思维、DP思想)
    立方数(质因子、优化)
    碎碎念(DP)
    牛牛战队的比赛地(三分)
    子段乘积(尺取、逆元)
    子段异或(位运算)
  • 原文地址:https://www.cnblogs.com/zhaobinyouth/p/9959914.html
Copyright © 2011-2022 走看看