1.Array.h,Array<T>的定义

template <class T>
class Array
{
protected:
T *data; //一个指向数组数据的指针
unsigned int base; //base为数组的起始下表
unsigned int length; //length为数组的长度
public:
Array(); //缺省的构造函数
Array(unsigned int, unsigned int = ); //数组构造函数
~Array(); //析构函数 Array(Array const&); //拷贝构造函数
Array& operator = (Array const&); //重载等号操作符,用于一个数组给另外一个数组赋值 T const& operator [] (unsigned int) const; //重载中括号操作符,返回一个T数值常量,返回值不能被改变,在函数末尾加const表示this指针指向const
T& operator [] (unsigned int); //重载中括号操作符,返回一个T数值常量,其返回值可以被改变 T* Data() const; //返回数组数据的指针data
unsigned int Base() const; //返回成员base
unsigned int Length() const; //返回成员length void SetBase(unsigned int); //设置成员变量base的数值
void SetLength(unsigned int); //设置成员变量length的数值
}; //动态数组所占空间S(n)=sizeof(T*)+2sizeof(unsigned int)+nsizeof(T),假定T类型所占用空间为一个常数,故S(n)=O(n)

2.Array<T>中成员函数的实现

#include "Array.h"

template <class T>
Array<T>::Array() :
data(new T[]),
base(),
length()
{}
//缺省的构造函数不含变量,只需要给对象的变量一个初始值,时间复杂度O(1) template <class T>
Array<T>::Array(unsigned int n, unsigned int m) :
data(new T[n]),
base(m),
length(n)
{}
//初始化数组,n为数组的长度,时间复杂度常量O(1) template <class T>
Array<T>::Array(Array<T> const& array) :
data(new T[array.length]),
base(array.base),
length(array.length)
{
for (unsigned int i = ; i < length; ++i)
data[i] = array.data[i];
} //备份构造函数,将一个数组从赋值到另外一个数组,时间复杂度为O(n) template <class T>
Array<T>::~Array()
{
delete[] data;
} //析构函数,删除数组所占用的内存空间 template <class T>
T* Array<T>::Data() const
{
return data;
} template <class T>
unsigned int Array<T>::Base() const
{
return base;
} template <class T>
unsigned int Array<T>::Length() const
{
return length;
} //这三个为存取器函数,用来返回成员,时间复杂度都为O(1) template <class T>
T const& Array<T>::operator[] (unsigned int position) const
{
unsigned int const offset = position - base;
if (offset >= length)
throw out_of_range("invalid position");
return data[offset];
} template <class T>
T& Array<T>::operator[] (unsigned int position)
{
unsigned int const offset = position - base;
if (offset >= length)
throw out_of_range("invalid position");
return data[offset];
}
//这两个都为取下表操作符的重载,区别是第一个返回值不可以作为左值,第二个返回值可以作为左值,时间复杂度都为O(1) template <class T>
void Array<T>::SetBase(unsigned int newBase)
{
base = newBase;
} template <class T>
void Array<T>::SetLength(unsigned int newLength)
{
T* const newData = new T[newLength];
unsigned int const min = length < newLength ? length : newLength;
for (unsigned int i = ; i < min; ++i)
newData[i] = data[i];
delete[] data;
data = newData;
length = newLength;
} //这两个函数来重设对象的成员,时间复杂度为T(m,n)=min(m,n)*T(T::T(T&))+O(1) template <class T>
Array<T>& Array<T>::operator = (Array<T> const& array)
{
if (this != &array)
{
delete[] data;
base = array.base;
length = array.length;
data = new T[length];
for (unsigned int i = ; i < length; ++i)
data[i] = array.data[i];
}
return this;
} //重载赋值操作符,时间复杂度为O(n)

3.测试主函数main.cpp

#include "Array.cpp"
#include <iostream>
using namespace std; template <class T> void Output(Array<T> array); template <class T>
void Output(Array<T> array)
{
cout << "data:";
for (unsigned int i = array.Base(); i < array.Length(); i++)
{
cout << array.Data()[i] << " ";
}
cout << endl;
cout << "length:" << array.Length()<<endl;
cout << "base:" << array.Base() <<endl;
} int main()
{
cout << "Array()正在执行。。。" << endl;
Array<int> array0 = Array<int>();
Output(array0);
cout << "Array(unsigned int, unsigned int = 0)正在执行。。。" << endl;
Array<int> array1 = Array<int>();
Output(array1);
cout << "Array(Array const&)正在执行。。。" << endl;
Array<int> array2(array1);
Output(array2);
cout << "~Array()正在执行。。。" << endl;
array2.~Array();
Output(array2);
cout << "T const* Data() const,unsigned int Base() const,unsigned int Length() const,"
<< "T const& operator [] (unsigned int) const在Output函数中执行。。。" << endl;
cout << "T& operator [] (unsigned int)正在执行。。。" << endl;
Array<int> array3();
for (unsigned int i = array1.Base(); i < array1.Length() - array1.Base(); i++)
{
array3.Data()[i] = i;
}
Output(array3);
cout << "void SetBase(unsigned int)正在执行。。。" << endl;
array3.SetBase();
Output(array3);
cout << "void SetLength(unsigned int)正在执行。。。" << endl;
array3.SetLength();
Output(array3);
getchar();
return ;
}

4.测试结果

c++实现的Array数据结构的更多相关文章

  1. 【Codeforces 722C】Destroying Array (数据结构、set)

    题意 输入一个含有 n(1≤n≤100000) 个非负整数的 a 数组和一个 1-n 的排列 p 数组,求每次删除 a[p[i]] 后,最大连续子段和(不能跨越被删除的)是多少? 分析 因为都是非负整 ...

  2. Set,Map与Array,Object对比

    Map与Array 数据结构横向对比,用Map和Array分别实现最基本的增删改查: //增 { let theMap=new Map(); let theArray=[]; theMap.set(' ...

  3. Spark Shuffle原理、Shuffle操作问题解决和参数调优

    摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuff ...

  4. 【转载】Spark性能优化指南——高级篇

    前言 数据倾斜调优 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 查看导致数据倾斜的key的数据分布情况 数据倾斜的解决方案 解决方案一:使用Hive ETL预处理数 ...

  5. 关于R中的mode()和class()的区别

    本文原创,转载请注明出处,本人Q1273314690(交流学习) 说明:本文曾经在15年11月在CSDN发过,但是由于CSDN不支持为知笔记的发布为博客的API功能,所以,自今天起,转移到博客园(幸好 ...

  6. 【转】【技术博客】Spark性能优化指南——高级篇

    http://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651745207&idx=1&sn=3d70d59cede236e ...

  7. [GeekBand] 探讨C++新标准之新语法——C++ 11~14

    一. 可变参数模板(Variadic Templates) 在C++11中,出现了参数数目可变的模板,这部分在之前C++高级编程的时候就有学习到. 其实,在C中就有类似的设定.最常用的printf() ...

  8. JavaScript数组知识网络

    JavaScript数据类型 基本数据类型 Boolean Null Number String Symbol Undefined 对象数据类型Object Build-in object Array ...

  9. Web前端:博客美化:二、鼠标特效

    1.获取JS权限 因为是js代码所以需要放在 侧边栏公告 里 没开通之前,有一个申请的链接,点击即可,我是第二天才看到过审的 ^-^ 2.Ctrl+C.Ctrl+V 数组里的文字随自己心情啦 另:30 ...

随机推荐

  1. 【VirtualDOM】

    前沿技术解密——VirtualDOM miniflycn/qvd Matt-Esch/virtual-dom Facebook React 和 Web Components(Polymer)对比优势和 ...

  2. 转 ---- Asp.net mvc项目分页功能

    1.定义一个分页用的Page<T>类 1 /* 使用示例: 2 var pager = new Pager<Article>( 3 this.ControllerContext ...

  3. main函数的3个参数

    最早是在MCU中使用C语言,MCU中的main函数没有参数. 后来在PC上面使用C语言,一般教程都写的是main函数有2个参数: int main(int argc, const char **arg ...

  4. 《University Calculus》-chape12-偏导数-基本概念

    偏导数本质上就是一元微分学向多元函数的推广. 关于定义域的开域.闭域的推广: 其实这个定义本质上讲的就是xoy面上阴影区域的最外面的一周,只不过这里用了更加规范的数学语言. 二次函数的图形.层曲线(等 ...

  5. 最常用的 Eclipse 快捷键总结

    本文是一些最实用.最齐全.最省时间的 Eclipse 快捷键总结,这些快捷键可以让帮助你完成工作中的任何一个操作.欢迎参考. 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间 ...

  6. oracle sysdba用户远程登录

    sysdba远程登录需要两个条件: 1.remote_login_passwordfile =exclusive时,启用口令文件,允许远程登录: 查看remote_login_passwordfile ...

  7. 数据库的发展现状与前景——NewSQL界的佼佼者,如Couchbase、Aerospike、Marklogic和 SequoiaDB,NewSQL的许多厂商,如:MemSQL、VoltDB、ScaleDB和CitusDB

    转自:http://news.sequoiadb.com/cn/Detail-id-42 2015-03-20   Strata+Hadoop World(SHW)大会是全世界最大的大数据大会之一. ...

  8. String的成员方法的使用

    <%@ page language="java" contentType="text/html; charset=gbk"%> <html&g ...

  9. ecshop获取浏览器各个版本

    <?php /** * 获得浏览器名称和版本 * * @access public * @return string */ function get_user_browser() { if (e ...

  10. 关于assert的学习

    编写代码时,总会做出一些假设,断言就是用于在代码中捕捉这些假设, 可以将断言看成是异常处理的一种高级形式. c语言assert宏的定义, #include <assert.h> void ...