一、实验任务四
模拟实验任务2,不使用标准库模板类vector,自己动手设计并实现一个动态的整型数组类Vector_int,
使其支持以下要求:
支持在创建int型数组对象时,指定其大小
支持在创建int型数组对象时,指定其大小,并将数组对象中每个数据项初始化到特定的值value
支持用已经存在的int型数组对象x,来构造新的int型数组对象y(要求实现深复制)
提供方法at()能够支持诸如 x.at(i) 这样通过索引访问动态int型数组对象中第i个数据项
析构函数,释放占用的内存资源
在构造和析构函数里,增加打印输出信息。运行程序时,帮助观察资源是否正确释放。
即在测试代码中,支持形如下面的代码操作:
要求:
① 设计并实现动态整型数组类Vector_int,保存在文件vector_int.hpp中
② 编写测试代码文件task4.cpp,测试其构造函数接口、复制构造函数、at()方法等,是否都正常使用,
是否实现了深复制。
分析过后代码如下:
Vector_int.hpp如下:
1 #include<iostream> 2 #include<cassert> 3 using namespace std; 4 5 class Vector_int 6 { 7 private: 8 int n,x;//n为数组长度,x为默认初始值 9 int *p;//数组 10 public: 11 Vector_int(int n0):n(n0),x(0) 12 { 13 p=new int[n]; 14 for(int i=0;i<n0;i++) 15 p[i]=x; 16 };//构造函数 17 Vector_int(int n0,int x0):n(n0),x(x0) 18 { 19 p=new int[n]; 20 for(int i=0;i<n0;i++) 21 p[i]=x; 22 };//构造函数 23 Vector_int(const Vector_int &y)//复制构造函数 24 { 25 n=y.n; 26 x=y.x; 27 p=new int[n]; 28 for(int i=0;i<n;i++) 29 p[i]=y.p[i]; 30 } 31 32 void print() const;//输出 33 ~Vector_int()//析构函数 34 { 35 delete[] p; 36 cout<<"destructor called"<<endl; 37 } 38 39 int &at(int index);//返回下标为index的数据引用 40 41 42 }; 43 44 void Vector_int::print() const{ 45 for(int i=0;i<n;i++){ 46 cout<<p[i]<<" "; 47 } 48 cout<<endl; 49 50 } 51 52 int &Vector_int::at(int index) 53 { 54 assert(index >= 0 && index < n); 55 return p[index]; 56 }
task4.cpp如下:
1 #include<iostream> 2 #include"Vector_int.hpp" 3 using namespace std; 4 int main() 5 { 6 int n; 7 cout<<"请输入数组长度:\n"; 8 cin>>n; 9 Vector_int x0(n); 10 cout<<"x0="; 11 x0.print(); 12 int n1,x; 13 cout<<"请输入数组长度和初始值:\n"; 14 cin>>n1>>x; 15 Vector_int x1(n1, x); 16 cout<<"x1="; 17 x1.print(); 18 Vector_int y(x1); 19 cout<<"y="; 20 y.print(); 21 y.at(0) = 999; 22 cout<<"y="; 23 y.print(); 24 return 0; 25 }
运行结果如下:

二、实验任务五
实现一个动态矩阵类Matrix,类Matrix的声明见文件Matrix.hpp。
① 实现类Matrix的定义
② 使用task5.cpp测试矩阵类Matrix。
经过分析后,Matrix.hpp如下:
1 #ifndef MATRIX_H 2 #define MATRIX_H 3 4 #include <iostream> 5 #include <cassert> 6 using namespace std; 7 class Matrix 8 { 9 public: 10 Matrix(int n); // 构造函数,构造一个n*n的矩阵 11 Matrix(int n, int m); // 构造函数,构造一个n*m的矩阵 12 Matrix(const Matrix &X); // 复制构造函数,使用已有的矩阵X构造 13 ~Matrix() //析构函数 14 { 15 delete[] p; 16 cout<<"destructor called\n"; 17 } 18 void set(const double *pvalue); // 用pvalue指向的连续内存块数据为矩阵赋值 19 void set(int i, int j, int value); //设置矩阵第i行第j列元素值为value 20 double &at(int i, int j); //返回矩阵第i行第j列元素的引用 21 double at(int i, int j) const; // 返回矩阵第i行第j列元素的值 22 int get_lines() const; //返回矩阵行数 23 int get_cols() const; //返回矩列数 24 void print() const; // 按行打印输出矩阵 25 private: 26 int lines; // 矩阵行数 27 int cols; // 矩阵列数 28 double *p; // 指向存放矩阵数据的内存块的首地址 29 }; 30 31 Matrix::Matrix(int n):lines(n),cols(n) 32 { 33 p=new double[n*n]; 34 } 35 36 Matrix::Matrix(int n,int m):lines(n),cols(m) 37 { 38 p=new double[n*m]; 39 } 40 41 Matrix::Matrix(const Matrix &X ):lines(X.lines),cols(X.cols) 42 { 43 p=new double[lines*cols]; 44 for(int i=0;i<lines*cols;i++) 45 p[i]=X.p[i]; 46 } 47 48 void Matrix::set(const double *pvalue) 49 { 50 for(int i=0; i<lines*cols; i++) 51 p[i]=*(pvalue+i); 52 } 53 54 void Matrix::set(int i,int j,int value) 55 { 56 assert((i >= 0 && i < lines) && (j >= 0 && j < cols)); 57 p[i*cols+j]=value; 58 } 59 60 double Matrix::at(int i, int j) const { 61 assert((i >= 0 && i < lines) && (j >= 0 && j < cols)); 62 return p[i*cols+j]; 63 } 64 double & Matrix::at(int i, int j) { 65 return p[i*cols+j]; 66 } 67 68 int Matrix::get_lines() const { 69 return lines; 70 } 71 int Matrix::get_cols() const { 72 return cols; 73 } 74 75 void Matrix::print() const { 76 for(int i=0; i<lines; i++) { 77 for(int j=0; j<cols; j++) { 78 cout<<p[i*cols+j]<<" "; 79 } 80 81 cout<<endl; 82 } 83 } 84 85 86 87 88 89 #endif
task5.cpp如下:
1 #include <iostream> 2 #include "Matrix.hpp" 3 4 int main() 5 { 6 using namespace std; 7 8 double x[] = {1, 2, 3, 4, 5, 6}; 9 10 Matrix m1(3, 2); // 创建一个3×2的矩阵 11 m1.set(x); // 用一维数组x的值按行为矩阵m1赋值 12 m1.print(); // 打印矩阵m1的值 13 cout << "the first line is: " << endl; 14 cout << m1.at(0, 0) << " " << m1.at(0, 1) << endl; 15 cout << endl; 16 17 Matrix m2(2, 3); 18 m2.set(x); 19 m2.print(); 20 cout << "the first line is: " << endl; 21 cout << m2.at(0, 0) << " " << m2.at(0, 1) << " " << m2.at(0, 2) << endl; 22 cout << endl; 23 24 Matrix m3(m2); 25 m3.set(0, 0, 999); 26 m3.print(); 27 }
运行结果如图:

三、实验结论
1.引用是没有自己的地址的,指针有自己的地址
2.引用作为形参时,例如&x,作为实参时要用x;
指针作为形参时,例如*x,作为实参要用&x.
3.*pa=a时,&pa是自己的地址,pa是a的地址
&ra=a时,&ra是a的地址,ra是a的值
4.在类中如果需要一组数组,可以用指针来帮助解决这种问题,例如定义*p,p=new double[]
5.assert是标准c++头文件cassert中定义的一个宏,用来判断一个条件表达式的值是否为true。
如果是false,会终止。
6.引用类型的函数其实现时也要用引用类型,例如double & Matrix::at(int i, int j)
7.自己构造一个容器时,例如vector,有一个数组指针*p,在构造函数中也要初始化它,初始化具体语句为:
p=new int[n]; for(int i=0;i<n0;i++) p[i]=x;
浙公网安备 33010602011771号