实验三 类与指针、数组
实验任务1
1 #pragma once 2 3 #include <iostream> 4 using std::cout; 5 using std::endl; 6 7 class Point { 8 public: 9 Point(int x0 = 0, int y0 = 0); 10 ~Point() = default; 11 12 int get_x() const; 13 int get_y() const; 14 void show() const; 15 void move(int new_x, int new_y); 16 17 private: 18 int x, y; 19 }; 20 21 Point::Point(int x0, int y0): x{x0}, y{y0} { 22 } 23 24 int Point::get_x() const { 25 return x; 26 } 27 28 int Point::get_y() const { 29 return y; 30 } 31 32 void Point::show() const { 33 cout << "(" << x << ", " << y << ")" << endl; 34 } 35 36 void Point::move(int new_x, int new_y) { 37 x = new_x; 38 y = new_y; 39 }
1 #include <iostream> 2 #include "point.hpp" 3 #include <vector> 4 5 using std::vector; 6 using std::cin; 7 8 void output(const vector<Point> &v) { 9 for(auto &t: v) 10 t.show(); 11 } 12 13 void test() { 14 int n; 15 cout << "输入动态Point数组类对象中元素个数: "; 16 cin >> n; 17 18 vector<Point> x(n); 19 cout << "x对象中所有点坐标信息: " << endl; 20 output(x); 21 22 vector<Point> y(x); 23 cout << "\ny对象中所有点坐标信息: " << endl; 24 output(y); 25 26 cout << "\n更新x对象......" << endl; 27 x.at(0).move(30, 50); 28 x.push_back(Point(2, 2)); 29 30 cout << "\nx对象中所有点坐标信息: " << endl; 31 output(x); 32 cout << "\ny对象中所有点坐标信息: " << endl; 33 output(y); 34 } 35 36 int main() { 37 test(); 38 }

问题1:对x对象进行更新时,基于 vector<Point> 对象x创建的对象y是否发生变化?
不发生
问题2:标准库模板类vector在复制一个动态数组对象时,实现的是深复制还是浅复制?
深复制
实验任务2
1 #pragma once 2 3 #include <iostream> 4 using std::cout; 5 using std::endl; 6 7 class Point { 8 public: 9 Point(int x0 = 0, int y0 = 0); 10 ~Point() = default; 11 12 int get_x() const; 13 int get_y() const; 14 void show() const; 15 void move(int new_x, int new_y); 16 17 private: 18 int x, y; 19 }; 20 21 Point::Point(int x0, int y0): x{x0}, y{y0} { 22 } 23 24 int Point::get_x() const { 25 return x; 26 } 27 28 int Point::get_y() const { 29 return y; 30 } 31 32 void Point::show() const { 33 cout << "(" << x << ", " << y << ")" << endl; 34 } 35 36 void Point::move(int new_x, int new_y) { 37 x = new_x; 38 y = new_y; 39 }
1 #pragma once 2 3 #include "point.hpp" 4 #include <cassert> 5 #include <iostream> 6 7 class vectorPoint{ 8 public: 9 vectorPoint(int n); 10 ~vectorPoint(); 11 12 int get_size() const; 13 Point& at(int index); 14 Point& at(int index) const; 15 vectorPoint(const vectorPoint &vp); 16 17 private: 18 int size; 19 Point *ptr; 20 }; 21 22 vectorPoint::vectorPoint(int n) : size{n} { 23 ptr = new Point[n]; 24 } 25 26 vectorPoint::~vectorPoint() { 27 delete[] ptr; 28 } 29 30 int vectorPoint::get_size() const { 31 return size; 32 } 33 34 Point& vectorPoint::at(int index) { 35 assert(index >= 0 && index < size); 36 return ptr[index]; 37 } 38 39 Point& vectorPoint::at(int index) const { 40 assert(index >= 0 && index < size); 41 return ptr[index]; 42 } 43 44 vectorPoint::vectorPoint(const vectorPoint &vp): size{vp.size}, ptr{vp.ptr} { 45 }
1 #include "vectorPoint.hpp" 2 #include <iostream> 3 4 void output(const vectorPoint &v) { 5 for(auto i = 0; i < v.get_size(); ++i) 6 v.at(i).show(); 7 } 8 9 10 void test() { 11 using namespace std; 12 13 int n; 14 cout << "输入vectorPoint对象中元素个数: "; 15 cin >> n; 16 17 vectorPoint x(n); 18 cout << "x对象中所有点坐标信息: " << endl; 19 output(x); 20 21 vectorPoint y(x); 22 cout << "\ny对象中所有点坐标信息: " << endl; 23 output(y); 24 25 cout << "\n更新x对象中点坐标信息......" << endl; 26 x.at(0).move(30, 50); 27 x.at(1).move(-1, -1); 28 29 cout << "x对象中所有点坐标信息: " << endl; 30 output(x); 31 32 cout << "\ny对象中所有点坐标信息: " << endl; 33 output(y); 34 } 35 36 int main() { 37 test(); 38 }

问题1:观察更新对象x后,基于 vectorPoint 对象x创建的对象y是否发生变化?
发生
问题2:编译器为vectorPoint类创建的默认复制构造函数,在复制一个动态数组对象时,实现
的是深复制还是浅复制?
浅复制
问题3:在类vectorPoint内部,手动增加的以下复制构造函数声明和定义,实现的是浅复制还
是深复制?
浅复制
实验任务3
1 #pragma once 2 3 #include <iostream> 4 using std::cout; 5 using std::endl; 6 7 class Point { 8 public: 9 Point(int x0 = 0, int y0 = 0); 10 ~Point() = default; 11 12 int get_x() const; 13 int get_y() const; 14 void show() const; 15 void move(int new_x, int new_y); 16 17 private: 18 int x, y; 19 }; 20 21 Point::Point(int x0, int y0): x{x0}, y{y0} { 22 } 23 24 int Point::get_x() const { 25 return x; 26 } 27 28 int Point::get_y() const { 29 return y; 30 } 31 32 void Point::show() const { 33 cout << "(" << x << ", " << y << ")" << endl; 34 } 35 36 void Point::move(int new_x, int new_y) { 37 x = new_x; 38 y = new_y; 39 }
1 #pragma once 2 3 #include "point.hpp" 4 #include <cassert> 5 #include <iostream> 6 7 class vectorPoint{ 8 public: 9 vectorPoint(int n); 10 vectorPoint(const vectorPoint &vp); 11 ~vectorPoint(); 12 13 int get_size() const; 14 Point& at(int index); 15 Point& at(int index) const; 16 17 private: 18 int size; 19 Point *ptr; 20 }; 21 22 vectorPoint::vectorPoint(int n) : size{n} { 23 ptr = new Point[n]; 24 } 25 26 vectorPoint::vectorPoint(const vectorPoint &vp): size{vp.size}, ptr{new Point[size]} { 27 for(auto i = 0; i < size; ++i) 28 ptr[i] = vp.ptr[i]; 29 } 30 31 vectorPoint::~vectorPoint() { 32 delete[] ptr; 33 } 34 35 int vectorPoint::get_size() const { 36 return size; 37 } 38 39 Point& vectorPoint::at(int index) { 40 assert(index >= 0 && index < size); 41 return ptr[index]; 42 } 43 44 Point& vectorPoint::at(int index) const { 45 assert(index >= 0 && index < size); 46 return ptr[index]; 47 }
1 #include "vectorPoint.hpp" 2 #include <iostream> 3 4 void output(const vectorPoint &v) { 5 for(auto i = 0; i < v.get_size(); ++i) 6 v.at(i).show(); 7 } 8 9 void test() { 10 using namespace std; 11 12 int n; 13 cout << "输入vectorPoint对象中元素个数: "; 14 cin >> n; 15 16 vectorPoint x(n); 17 cout << "x对象中所有点坐标信息: " << endl; 18 output(x); 19 20 vectorPoint y(x); 21 cout << "\ny对象中所有点坐标信息: " << endl; 22 output(y); 23 24 cout << "\n更新x对象中点坐标信息......" << endl; 25 x.at(0).move(30, 50); 26 x.at(1).move(-1, -1); 27 28 cout << "x对象中所有点坐标信息: " << endl; 29 output(x); 30 31 cout << "\ny对象中所有点坐标信息: " << endl; 32 output(y); 33 } 34 35 int main() { 36 test(); 37 }

问题1:观察更新对象x后,基于 vectorPoint 对象x创建的对象y是否发生变化?
发生变化
问题2:这个vectorPoint 类的实现中,复制构造函数实现的是深复制还是浅复制?
浅复制
问题3:基于实验任务2和3,总结当类的成员中包含指针域成员时深复制与浅复制的区别。
深复制会创建一个新的对象,并将指针域成员指向的内容也进行复制;浅复制只是简单地将指针域成员的地址拷贝给新对象。
实验任务4
1 #include <iostream> 2 using namespace std; 3 4 void swap1(int &rx, int &ry); 5 void swap2(int *px, int *py); 6 void print(int x, int y); 7 8 void test() { 9 int x = 3, y = 4; 10 11 print(x, y); 12 swap1(x, y); 13 print(x, y); 14 15 cout << endl; 16 17 x = 3, y = 4; 18 print(x, y); 19 swap2(&x, &y); 20 print(x, y); 21 } 22 23 int main() { 24 test(); 25 } 26 27 28 void swap1(int &rx, int &ry) { 29 int t; 30 31 t = rx; rx = ry; ry = t; 32 } 33 34 void swap2(int *px, int *py) { 35 int t; 36 37 t = *px; *px = *py; *py = t; 38 } 39 40 void print(int x, int y) { 41 std::cout << "x = " << x << ", y = " << y << "\n"; 42 }

1 #include <iostream> 2 #include <typeinfo> 3 using namespace std; 4 5 int main() { 6 int a; 7 8 int &ra = a; 9 ra = 4; 10 11 int *pa = &a; 12 *pa = 5; 13 14 cout << "&a = " << hex << &a << endl; 15 cout << "&ra = " << hex << &ra << endl; 16 cout << "&pa = " << hex << &pa << "\n\n"; 17 18 cout << "a = " << a << endl; 19 cout << "ra = " << a << endl; 20 cout << "pa = " << hex << pa << endl; 21 22 cout << "*pa = " << *pa << "\n\n"; 23 24 cout << "type a: " << typeid(a).name() << endl; 25 cout << "type ra: " << typeid(ra).name() << endl; 26 cout << "type pa: " << typeid(pa).name() << endl; 27 }

1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 template<typename T> 7 void output(const T &x) { 8 for(auto i: x) 9 std::cout << i << ", "; 10 std::cout << "\b\b \n"; 11 } 12 13 template<typename T> 14 void square1(T &x) { 15 for(auto i: x) 16 i *= i; 17 } 18 19 template<typename T> 20 void square2(T &x) { 21 for(auto &i: x) 22 i *= i; 23 } 24 25 void test1() { 26 vector<int> x {1, 2, 3, 4, 5}; 27 28 cout << "动态int型数组对象x内的元素值: "; 29 output(x); 30 31 cout << "调用函数square1()......" << endl; 32 square1(x); 33 34 cout << "动态int型数组对象x内的元素值: "; 35 output(x); 36 } 37 38 void test2() { 39 vector<int> x {1, 2, 3, 4, 5}; 40 41 cout << "动态int型数组对象x内的元素值: "; 42 output(x); 43 44 cout << "调用函数square2()......" << endl; 45 square2(x); 46 47 cout << "动态int型数组对象x内的元素值: "; 48 output(x); 49 } 50 51 int main() { 52 cout << "测试1: " << endl; 53 test1(); 54 55 cout << "\n测试2: " << endl; 56 test2(); 57 }

用文字总结引用类型、指针类型的区别
引用类型是一个别名,指向已经存在的对象或变量,不需要分配新的内存空间;指针类型是一个变量,存储另一对象或变量的地址,并可以通过解引用操作访问该地址处的值。
实验任务5
1 #ifndef VECTORINT_HPP 2 3 #define VECTORINT_HPP 4 5 #include <iostream> 6 7 8 class vectorInt { 9 private: 10 int* data; // 动态数组指针 11 int size; // 数组大小 12 13 public: 14 // 构造函数,动态指定数组大小,并初始化每个数据项为0 15 vectorInt(int n) : size(n) { 16 std::cout << "constructor vectorInt(int n) called." << std::endl; 17 data = new int[size]; 18 for (int i = 0; i < size; ++i) { 19 data[i] = 0; 20 } 21 } 22 23 // 构造函数,动态指定数组大小,并初始化每个数据项为特定值value 24 vectorInt(int n, int value) : size(n) { 25 std::cout << "constructor vectorInt(int n, int value) called." << std::endl; 26 data = new int[size]; 27 for (int i = 0; i < size; ++i) { 28 data[i] = value; 29 } 30 } 31 32 // 复制构造函数,实现深复制 33 vectorInt(const vectorInt& other):size(other.size){ 34 std::cout<<"copy constructor called."<<std::endl; 35 this->data=new int[this->size]; 36 for(int i=0;i<this->size;++i){ 37 this->data[i]=other.data[i]; 38 } 39 } 40 41 // 析构函数,释放内存资源 42 ~vectorInt(){ 43 std::cout<<"destructor called"<<std::endl; 44 delete[] this->data; 45 } 46 47 // 获取数组大小的方法 48 int get_size() const{ 49 return this->size; 50 } 51 52 // 通过索引访问数组元素的方法 53 int& at(int index){ 54 return this->data[index]; 55 } 56 }; 57 58 #endif
1 #include "vectorInt.hpp" 2 #include <iostream> 3 4 using std::cout; 5 using std::cin; 6 using std::endl; 7 8 void output(const vectorInt &vi) { 9 for (int i = 0; i < vi.get_size(); ++i) { 10 cout << vi.at(i) << " "; 11 } 12 cout << endl; 13 } 14 15 void test() { 16 int n; 17 cout << "输入vectorInt对象中元素个数: "; 18 cin >> n; 19 20 vectorInt x1(n); 21 for(auto i = 0; i < n; ++i) 22 x1.at(i) = i*i; 23 cout << "vectorInt对象x1: " ; 24 output(x1); 25 26 27 vectorInt x2(n, 42); 28 cout << "vectorInt对象x2: " ; 29 output(x2); 30 vectorInt x3(x2); 31 cout << "vectorInt对象x3: " ; 32 output(x3); 33 34 cout << "更新vectorInt对象x2......\n" ; 35 x2.at(0) = 77; 36 x2.at(1) = -999; 37 38 cout << "vectorInt对象x2: "; 39 output(x2); 40 cout << "vectorInt对象x3: "; 41 output(x3); 42 } 43 44 int main() { 45 test(); 46 } 47 48 task5.cpp

实验任务6
1 #pragma once 2 3 #include <iostream> 4 5 #include <cassert> 6 7 8 using std::cout; 9 using std::endl; 10 11 class Matrix { 12 public: 13 Matrix(int n, int m); 14 Matrix(int n); 15 Matrix(const Matrix &x); 16 ~Matrix(); 17 void set(const double *pvalue); // 矩阵赋值 18 void set(int i, int j, double value); // 设置矩阵对象索引(i,j)的元素值为value 19 const double& at(int i, int j) const; // 返回矩阵对象索引(i,j)的元素引用 20 double& at(int i, int j); // 返回矩阵对象索引(i,j)的元素引用 21 int getlines() const; // 返回矩阵对象行数 22 int getcols() const; // 返回矩阵对象列数 23 void print() const; // 按行打印输出矩阵对象元素值 24 25 private: 26 int lines; 27 int cols; 28 double *ptr; 29 }; 30 31 32 33 Matrix::Matrix(int n, int m) : lines(n), cols(m) 34 { 35 assert(lines > 0 && cols > 0); 36 37 ptr = new double[lines * cols]; 38 } 39 40 Matrix::Matrix(int n) : lines(n), cols(n) 41 { 42 assert(lines > 0); 43 44 ptr = new double[lines * cols]; 45 } 46 47 Matrix::~Matrix() 48 { 49 delete[] ptr; 50 } 51 52 void Matrix::set(const double* pvalue) 53 { 54 for (int i = 0; i < lines * cols; ++i) 55 ptr[i] = pvalue[i]; 56 } 57 58 void Matrix::set(int i, int j, double value) 59 { 60 assert(i >= 0 && i < lines); 61 assert(j >= 0 && j < cols); 62 63 ptr[i * cols + j] = value; 64 } 65 66 const double& Matrix::at(int i, int j) const 67 { 68 assert(i >= 0 && i < lines); 69 assert(j >= 0 && j < cols); 70 71 return ptr[i * cols + j]; 72 } 73 74 double& Matrix::at(int i, int j) 75 { 76 assert(i >= 0 && i < lines); 77 assert(j >= 0 && j < cols); 78 79 return ptr[i * cols + j]; 80 } 81 82 int Matrix::get_lines() const 83 { 84 return lines; 85 } 86 87 int Matrix::get_cols() const 88 { 89 return cols; 90 } 91 92 void Matrix::print() const 93 { 94 for (int i = 0; i < lines; ++i) 95 { 96 for (int j = 0; j < cols; ++j) 97 cout << at(i, j) << " "; 98 cout << endl; 99 } 100 }
1 #include <iostream> 2 #include "Matrix.hpp" 3 4 using namespace std; 5 6 const int N1 = 3; 7 const int N2 = 2; 8 9 void output(const Matrix &m, int index) { 10 for(auto j = 0; j < m.get_cols(); ++j) 11 cout << m.at(index, j) << ", "; 12 cout << "\b\b \n"; 13 } 14 15 void test() { 16 17 double x[N1*N2] = {2,4, 5, 7, 8, 9}; 18 19 Matrix m1(N1, N2); 20 m1.set(x); 21 cout << "矩阵对象m1: " << endl; 22 m1.print(); 23 cout << "矩阵对象m1第0行是: " << endl; 24 output(m1, 0); 25 cout << endl; 26 27 Matrix m2(N2, N1); 28 m2.set(x); 29 cout << "矩阵对象m2: " << endl; 30 m2.print(); 31 cout << "矩阵对象m2第0行是: " << endl; 32 output(m2, 0); 33 cout << endl; 34 35 Matrix m3(m2); 36 m3.set(0, 0, 999); 37 cout << "矩阵对象m3:" << endl; 38 m3.print(); 39 cout << endl; 40 41 Matrix m4(2); 42 m4.set(x); 43 cout << "矩阵对象m4:" << endl; 44 m4.print(); 45 } 46 47 int main() { 48 test(); 49 }

浙公网安备 33010602011771号