成都市市民服务热线:C 技巧:二维动态数组类模板

来源:百度文库 编辑:偶看新闻 时间:2024/06/11 13:57:51
C++提供了许多强大的机制来实现代码的高度复用、来使我们使用我们自已的类就像使用内置类型那样方便快捷。比如模板,运算符重载等等。模板好比如是一个大批量生产函数和类的工厂,使我们不用再去关心与数据类型相关的繁琐编程细节,把我们精力留给那些真正值得我们去认真思考的地方。而运算符重载则使我们的程序更直观更简洁,这不仅使我们更容易读懂我们的程序,而且使我们能以一种更为流畅的方式来表达我们的想法。就像上篇文章说到的,如果我们把动态分配的二维数组用类模板实现,并重载相应的操作符,我们就能十分方便的使用我们自己定义的数组类型了。今天我正好把以往的程序整理了一下,就一并贴了出来,看下面的程序。下面的两个类模板在vc++6.0上编译运行良好,测试程序也都得到正确的结果,如果在其他编译环境下有什么问题,欢迎给我留言。

    第一个头文件Array.h是一维动态数组类模板:

 //Array.h
#ifndef CARL_SEN_ARRAY_H
#define CARL_SEN_ARRAY_H

#include
#include
using std::out_of_range;
using std::ostream;

template
class Array {
protected:
unsigned int size;
T* data;
public:
//构造函数
Array(unsigned int _size=0);
Array(unsigned int count, T data1, ...);

//复制控制
Array(const Array& array);
Array& operator=(const Array& array);
~Array() {
delete[] data;
}
//两种重载运算符
T& operator[](unsigned int index);
const T& operator[](unsigned int index) const;
friend ostream& operator<<(ostream& os, const Array& array);

//get,set成员函数
unsigned int getSize() const {
return size;
}
void setSize(unsigned int newSize);
};

template
Array::Array(unsigned int _size):data(new T[_size]), size(_size) {
for(unsigned int i=0; idata[i]=T();
}
}

template
Array::Array(unsigned int count, T data1, ...):size(count), data(new T[count]) {
va_list ap;
va_start(ap, count);
for(unsigned int i=0; idata[i]=va_arg(ap, T);
}
va_end(ap);
}

template
Array::Array(const Array& array):size(array.size), data(new T[array.size]) {
for(unsigned int i=0; idata[i]=array.data[i];
}
}

template
Array& Array::operator=(const Array& array) {
if(&array!=this) {
delete[] data;
data=new T[array.size];
size=array.size;
for(unsigned int i=0; idata[i]=array.data[i];
}
}
return *this;
}

template
T& Array::operator[](unsigned int index) {
if(index>=size) {
throw out_of_range("invalid index");
}
return data[index];
}

template
const T& Array::operator[](unsigned int index) const {
if(index>=size) {
throw out_of_range("invalid index");
}
return data[index];
}

template
void Array::setSize(unsigned int newSize) {
T* const newData=new T[newSize];
const unsigned int Min=sizefor(unsigned int i=0; inewData[i]=data[i];
}
delete[] data;
data=newData;
size=newSize;
}

template
ostream& operator<<(ostream& os, const Array& array) {
for(int i=0; ios<}
return os;
}

#endif

第二个头文件Array2D.h是二维动态数组类模板:
//Array2D.h
#ifndef CARL_SEN_ARRAY2D_H
#define CARL_SEN_ARRAY2D_H

#include "Array.h"
#include
#include
using std::ostream;
using std::out_of_range;

template
class Array2D {
protected:
unsigned int rows;
unsigned int cols;
Array array;
public:
//构造函数
Array2D(unsigned int _rows=0, unsigned int _cols=0);
Array2D(unsigned int _rows, unsigned int _cols, T data1, ...);
//两种重载运算符
class RowArray;
RowArray operator[](unsigned int row);
const RowArray operator[](unsigned int row) const;
friend ostream& operator<<(ostream& os, const Array2D& array2D);

//计算第二维下标操作的嵌套类
class RowArray {
private:
const Array2D& array2D;
unsigned int row;
public:
RowArray(Array2D& _array2D, unsigned int _row=0):
array2D(_array2D), row(_row) {}
RowArray(const Array2D& _array2D, unsigned int _row=0):
array2D(_array2D), row(_row) {}
T& operator[](unsigned int col) {
if(col>=array2D.cols) {
throw out_of_range("invalid col");
}
return const_cast&>(array2D).array[row*array2D.cols+col];
}
const T& operator[](unsigned int col) const {
if(col>=array2D.cols) {
throw out_of_range("invalid col");
}
return array2D.array[row*array2D.cols+col];
}
};
friend class RowArray;

//get,set函数
unsigned int getRows() const {
return rows;
}
unsigned int getCols() const {
return cols;
}
};

template
Array2D::Array2D(unsigned int _rows, unsigned int _cols):
rows(_rows), cols(_cols), array(_rows*_cols){
for(unsigned int i=0; iarray[i]=T();
}
}

template
Array2D::Array2D(unsigned int _rows, unsigned int _cols, T data1, ...):
rows(_rows), cols(_cols),array(_rows*_cols){
va_list ap;
va_start(ap, _cols);
for(unsigned int i=0; iarray[i]=va_arg(ap, T);
}
va_end(ap);
}

template
Array2D::RowArray Array2D::operator[](unsigned int row) {
if(row>=rows) {
throw out_of_range("invalid row");
}
return RowArray(*this, row);
}

template
const Array2D::RowArray Array2D::operator[](unsigned int row) const {
if(row>=rows) {
throw out_of_range("invalid row");
}
return RowArray(*this, row);
}

template
ostream& operator<<(ostream& os, const Array2D& array2D) {
unsigned int i, j;
for(i=0; ifor(j=0; jos<}
if(i!=array2D.rows-1) {
os<}
}
return os;
}

#endif

现在就可以使用它们了,如下面的测试程序:
#include "Array.h"
#include "Array2D.h"
#include
#include
using std::string;
using std::cout;
using std::endl;

void testArray();
void testArray2D();

int main() {
testArray();
testArray2D();
return EXIT_SUCCESS;
}

void testArray() {
//普通数组
Array a1(3);
cout<<"Testing Array: print 1"<cout<
unsigned int i;
for(i=0; ia1[i]=i+1; //逐个赋值
}
cout<<"Testing Array: print 2"<for(i=0; icout<}
cout<
//常量数组
const Array a2(3, 123, 234, 345);
cout<<"Testing Array: print 3"<cout<cout<<"Testing Array: print 4"<for(i=0; icout<}
cout<
//拷贝构造
Array a3(a1);
cout<<"Testing Array: print 5"<cout<const Array a4(a2);
cout<<"Testing Array: print 6"<cout<
//数组赋值给数组
Array a5;
a5=a4;
cout<<"Testing Array: print 7"<cout<
//增减数组元素
a5.setSize(a5.getSize()+1);
a5[a5.getSize()-1]=111;
cout<<"Testing Array: print 8"<cout<a5.setSize(a5.getSize()-2);
cout<<"Testing Array: print 9"<cout<
//保存对象
Array a6(2, string("str0"), string("str1"));
cout<<"Testing Array: print 10"<cout<for(i=0; ia6[i]+=static_cast(48+i);
}
cout<<"Testing Array: print 11"<for(i=0; icout<}
cout<const Array a7(3, string("000"), string ("111"), string("222"));
cout<<"Testing Array: print 12"<cout<for(i=0; icout<}
cout<}

void testArray2D() {
//普通数组
Array2D a1(2, 2);
cout<<"Testing Array2D: print 1"<cout<unsigned int i,j;
for(i=0; ifor(j=0; ja1[i][j]=i+j;
}
}
cout<<"Testing Array2D: print 2"<for(i=0; ifor(j=0; jcout<}
cout<}

//常量数组
const Array2D a2(2, 2, 123, 234, 345, 456);
cout<<"Testing Array2D: print 3"<cout<cout<<"Testing Array2D: print 4"<for(i=0; ifor(j=0; jcout<}
cout<}
//拷贝构造
Array2D a3(a1);
cout<<"Testing Array2D: print 5"<cout<const Array2D a4(a2);
cout<<"Testing Array2D: print 6"<cout<

//数组赋值给数组
Array2D a5;
a5=a4;
cout<<"Testing Array2D: print 7"<cout<

//保存对象
Array2D a6(2, 2, string("str00"), string("str01"), string("str10"), string("str11"));
cout<<"Testing Array2D: print 8"<cout<for(i=0; ifor(j=0; ja6[i][j]+=static_cast(48+i+j);
}
}
cout<<"Testing Array2D: print 9"<for(i=0; ifor(j=0; jcout<}
cout<}
const Array2D a7(2, 1, string("11111"), string("22222"));
cout<<"Testing Array2D: print 10"<cout<cout<<"Testing Array2D: print 11"<for(i=0; ifor(j=0; jcout<}
cout<}
}