- 课程目标
— 完成 DynamicArray 类的具体实现
- DynamicArray 设计要点
— 类模板
动态确定内部数组空间的大小
实现函数返回数组长度
拷贝构造和赋值操作 - DynamicArray 类的声明
DynamicArray.h
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
#include "Array.h"
namespace DTLib
{
template<typename T>
class DynamicArray : public Array<T>
{
protected:
int m_length;
public:
DynamicArray(int length)
{
this->m_array = new T[length];
if(this->m_array != nullptr)
{
this->m_length = length;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no memory to creat DynamicArray Object...");
}
}
DynamicArray(const DynamicArray<T>& obj)
{
this->m_array = new T[obj.m_length];
if(this->m_array != nullptr)
{
for(int i = 0; i < obj.m_length; i++)
{
this->m_array[i] = obj.m_array[i];
}
this->m_length = obj.m_length;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no memory to copy the Object...");
}
}
DynamicArray<T>& operator=(const DynamicArray<T>& obj)
{
if(this != &obj)
{
T* array = new T[obj.m_length];
if(array != nullptr)
{
for(int i = 0; i < obj.m_length; i++)
{
array[i] = obj.m_array[i];
}
T* temp = this->m_array;
this->m_array = array;
this->m_length = obj.m_length;
delete []temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no memory to copy the Object...");
}
}
return *this;
}
void resize(int length)
{
if(this->m_length != length)
{
T* array = new T[length];
if(array != nullptr)
{
int len = (this->m_length < length ? this->m_length : length);
for(int i = 0; i < len; i++)
{
array[i] = this->m_array[i];
}
T* temp = this->m_array;
this->m_array = array;
this->m_length = length;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no memory to resize the Object...");
}
}
}
int length()const
{
return m_length;
}
~DynamicArray()
{
delete []this->m_array;
}
};
}
#endif // DYNAMICARRAY_H
main.cpp
#include <iostream>
#include "StaticArray.h"
#include "DynamicArray.h"
using namespace std;
using namespace DTLib;
int main()
{
DynamicArray<int> s1(5);
for(int i = 0; i < s1.length(); i++)
{
s1[i] = i * i;
}
for(int i = 0; i < s1.length(); i++)
{
cout << s1[i] << endl;
}
cout << endl;
DynamicArray<int> s2(10);
s2 = s1;
s2.resize(3);
for(int i = 0; i < s2.length(); i++)
{
cout << s2[i] << endl;
}
s2[4] = 100;
return 0;
}
- 问题
DynamicArray 类中的函数实现存在重复的逻辑,如何进行代码优化? - 重复代码逻辑的抽象
— init
对象构造时的初始化操作
— copy
在堆空间中申请新的内存,并执行拷贝操作
— update
将指定的堆空间作为内部存储数组使用
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
#include "Exception.h"
#include "Array.h"
namespace DTLib
{
template <typename T>
class DynamicArray : public Array<T>
{
protected:
int m_length;
T* copy(T* array, int len, int new_len) //把本来有的空间赋值给新申请的空间
{
T* ret = new T[new_len];
if(ret != nullptr)
{
int size = (len < new_len ? len : new_len);
for(int i = 0; i < size; i++)
{
ret[i] = array[i];
}
}
return ret;
}
void update(T* array, int length)
{
if(array != nullptr)
{
T* temp = this->m_array;
this->m_array = array;
this->m_length = length;
delete []temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to update the Object");
}
}
void init(T* array, int length)
{
if(array != nullptr)
{
this->m_array = array;
this->m_length = length;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to init the Object");
}
}
public:
DynamicArray(int length)
{
init(new T[length], length);
}
DynamicArray(const DynamicArray<T>& obj)
{
init(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length);
}
DynamicArray<T>& operator=(const DynamicArray<T>& obj)
{
if(this != &obj)
{
update(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length);
}
return *this;
}
void resize(int length)
{
if(this->m_length != length)
{
update(copy(this->m_array, m_length, length), length);
}
}
int length()const
{
return m_length;
}
~DynamicArray()
{
delete [](this->m_array);
}
};
}
#endif // DYNAMICARRAY_H
小结:
- StaticArray 通过封装原生数组的方式实现数组类
- DynamicArray 动态申请堆空间,使得数组长度动态可变
- 数组对象能够代替原生数组,并且使用上更安全
- 代码优化是项目开发过程中不可或缺的环节