zoukankan      html  css  js  c++  java
  • 第十九课 数组类的创建(上)

    基于顺序存储结构的线性表可能被当成数组来误用,这一节我们要设计数组类来代替原生数组。

    课程目标:

    Array是一个抽象类,这个类存在的意义就是用来被继承。

    需求分析:

     

    原生数组是不提供复制操作的,我们自己的数组要提供复制操作。

    length()成员函数设置为纯虚函数,说明这个类是一个纯虚类,用于被继承,具体实现在子类中完成。

     在工程中添加Array.h文件:

     1 #ifndef ARRAY_H
     2 #define ARRAY_H
     3 
     4 #include "Object.h"
     5 #include "Exception.h"
     6 
     7 namespace DTLib
     8 {
     9 
    10 template <typename T>
    11 class Array : public Object
    12 {
    13 protected:
    14     T* m_array;
    15 public:
    16     virtual bool set(int i, const T&e)    //O(1)
    17     {
    18         bool ret = ((0 <= i) && (i < length()));
    19 
    20         if( ret )
    21         {
    22             m_array[i] = e;
    23         }
    24     }
    25 
    26     virtual bool get(int i, T& e) const  //O(1)
    27     {
    28         bool ret = ((0 <= i) && (i < length()));
    29 
    30         if( ret )
    31         {
    32             e = m_array[i];
    33         }
    34     }
    35 
    36     T& operator[] (int i)   //O(1)
    37     {
    38         if((0 <= i) && (i < length()))
    39         {
    40             return m_array[i];
    41         }
    42         else
    43         {
    44             THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
    45         }
    46     }
    47 
    48     T operator[] (int i) const   //O(1)
    49     {
    50         return (const_cast<Array<T>>(*this))[i];
    51     }
    52 
    53     virtual int length() const = 0;
    54 };
    55 
    56 }
    57 
    58 #endif // ARRAY_H

    StaticArray设计:

    添加StaticArray.h文件,如下:

     1 #ifndef STATICARRAY_H
     2 #define STATICARRAY_H
     3 
     4 #include "Array.h"
     5 
     6 namespace DTLib
     7 {
     8 
     9 template <typename T, int N>
    10 class StaticArray : public Array<T>
    11 {
    12 protected:
    13     T m_space[N];
    14 public:
    15     StaticArray()   //O(1)
    16     {
    17         this->m_array = m_space;   //将定义的原生数组挂接到指针上去
    18     }
    19 
    20     StaticArray(const StaticArray<T, N>& obj)  //O(n)
    21     {
    22         this->m_array = m_space;
    23 
    24         for(int i = 0; i < N; i++)
    25         {
    26             m_space[i] = obj.m_space[i];
    27         }
    28     }
    29 
    30     StaticArray<T, N>& operator= (const StaticArray<T, N>& obj)  //O(n)
    31     {
    32         if( this != &obj )
    33         {
    34             for(int i = 0; i < N; i++)
    35             {
    36                 m_space[i] = obj.m_space[i];
    37             }
    38         }
    39 
    40         return *this;
    41     }
    42 
    43     int length() const   // O(1)
    44     {
    45         return N;
    46     }
    47 };
    48 
    49 }
    50 
    51 #endif // STATICARRAY_H

    测试程序如下:

     1 #include <iostream>
     2 #include "StaticArray.h"
     3 
     4 
     5 using namespace std;
     6 using namespace DTLib;
     7 
     8 
     9 int main()
    10 {
    11 
    12     StaticArray<int, 5> s1;
    13 
    14     for(int i = 0; i<s1.length(); i++)
    15     {
    16         s1[i] = i * i;
    17     }
    18 
    19     for(int i = 0; i < s1.length(); i++)
    20     {
    21         cout << s1[i] << endl;
    22     }
    23 
    24     return 0;
    25 }

    运行结果如下:

    第16、21行可以使用数组下标访问了,打印结果也是正确的。

    第二个测试程序:

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

    结果如下:

    可以看到第26行数组之间的赋值完全是合法的。

    修改测试程序:

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

    结果如下:

    可以看到33行的越界赋值引发了异常,这样做的好处是在有bug的地方立即抛出异常,而不是等到程序运行了很长时间才出现bug,那时候定位bug是很困难的。

     抛出异常这种方式不会引起bug的传播。有问题的地方就立即反应出来。

    原生数组是做不到这一点的。

  • 相关阅读:
    WebApi 2:属性路由 [Route()],attribute routing
    WebApi:路由和Action选择
    1024 科学计数法(20 分)
    1023 组个最小数(20 分)
    1022 D进制的A+B(20 分)
    1021 个位数统计(15 分)
    1020 月饼(25 分)
    1019 数字黑洞(20 分)
    1018 锤子剪刀布(20 分)
    1017 A除以B(20 分)
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9630618.html
Copyright © 2011-2022 走看看