课程目标

  • 完成 Array 类的具体实现
  • 完成 StaticArray 类的具体实现

image.png

需求分析

  • 创建数组类代替原生数组的使用

    • 数组类包含长度信息
    • 数组类能够主动发现越界访问

Array 要点设计

  • 抽象类模板,存储空间的位置和大小由子类完成
  • 重载数组操作符,判断访问下标是否合法
  • 提供数组长度的抽象访问函数
  • 提供数组对象间的复制操作

Array 类的声明

template <typename T>
class Array : public Object
{
public:
    virtual bool set(int i, const T &e);
    virtual bool get(int i, T &e) const;
    virtual int length() const = 0;
    
    T &operator[] (int i);
    T operator[] (int i) const;

protected:
    T *m_array;
};

编程实验:抽象数组类实现

#ifndef ARRAY_H
#define ARRAY_H

#include "Object.h"
#include "Exception.h"

namespace DTLib
{

template <typename T>
class Array : public Object
{
public:
    virtual bool set(int i, const T &e)  // O(1)
    {
        bool ret = ((0 <= i) && (i < length()));

        if (ret)
        {
            m_array[i] = e;
        }

        return ret;
    }

    virtual bool get(int i, T &e) const  // O(1)
    {
        bool ret = ((0 <= i) && (i < length()));

        if (ret)
        {
            e = m_array[i];
        }

        return ret;
    }

    T &operator[] (int i)  // O(1)
    {
        if ((0 <= i) && (i < length()))
        {
            return m_array[i];
        }
        else
        {
            THROW_EXCEPTION(IndexOutOfBoundsException, "Paramter i is invalid ...");
        }
    }

    T operator[] (int i) const  // O(1)
    {
        return const_cast<Array<T>&>(*this)[i];
    }

    virtual int length() const = 0;

protected:
    T *m_array = nullptr;
};

}

#endif // ARRAY_H

StaticArray 设计要点

  • 类模板

    • 封装原生数组
    • 使用模板参数决定数组大小
    • 实现函数返回数组长度
    • 拷贝和赋值操作

StaitcArray 类的声明

template <typename T, int N>
class StaticArray : public Array<T>
{
public:
    StaticArray();
    StaticArray(const StaticArray<T, N> &obj);
    StaticArray<T, N> &operator= (const StaticArray<T, N> &obj);
    
    int length() const;

protected:
    T m_space[N];
};

编程实验:静态数组类的实现

StaticArray.h

#ifndef STATICARRAY_H
#define STATICARRAY_H

#include "Array.h"

namespace DTLib
{

template <typename T, int N>
class StaticArray : public Array<T>
{
public:
    StaticArray()  // O(1)
    {
        this->m_array = m_space;
    }

    StaticArray(const StaticArray<T, N> &obj)  // O(n)
    {
        this->m_array = m_space;

        for (int i=0; i<N; ++i)
        {
            m_space[i] = obj.m_space[i];
        }
    }

    StaticArray<T, N> &operator= (const StaticArray<T, N> &obj)  // O(n)
    {
        if (this != &obj)
        {
            for (int i=0; i<N; ++i)
            {
                m_space[i] = obj.m_space[i];
            }
        }

        return *this;
    }

    int length() const  // O(1)
    {
        return N;
    }

protected:
    T m_space[N];
};

}

#endif // STATICARRAY_H

文件:main.cpp

#include <iostream>
#include "StaticArray.h"

using namespace std;
using namespace DTLib;

int main()
{
    cout << "main begin" << endl;

    StaticArray<int, 5> a;

    for (int i=0; i<a.length(); ++i)
    {
        a[i] = i * i;
    }

    for (int i=0; i<a.length(); ++i)
    {
        cout << a[i] << endl;
    }

    cout << "---------" << endl;

    StaticArray<int, 5> a1;

    a1 = a;

    for (int i=0; i<a1.length(); ++i)
    {
        cout << a1[i] << endl;
    }

    cout << "main end" << endl;

    return 0;
}

输出:

main begin
0
1
4
9
16
---------
0
1
4
9
16
main end

To be continued...

image.png

思考:
如歌实现DynamicArray?
DynamicArray 与 StaticArray 的差距在哪里?

以上内容整理于狄泰软件学院系列课程,请大家保护原创!


TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧