实验三 类与数组、指针
1.实验任务1
point.hpp
1 #include <iostream> 2 #include "point.hpp" 3 #include <vector> 4 using std::vector; 5 using std::cin; 6 // 输出vector<Point>对象内所有点的坐标 7 void output(const vector<Point>& v) { 8 for (auto& t : v) 9 t.show(); 10 } 11 void test() { 12 int n; 13 cin >> n; 14 vector<Point> x(n); 15 cout << "x对象中所有点坐标信息: " << endl; 16 output(x); 17 vector<Point> y(x); // 基于vector<Point>对象x构建对象y 18 cout << "\nx对象中所有点坐标信息: " << endl; 19 output(y); 20 cout << "\n更新x对象: " << endl; 21 x.at(0).move(30, 50); // 更新对象x内索引为0的点对象坐标 22 x.push_back(Point(2, 2)); // 向x对象末尾添加一个点对象 23 cout << "\nx对象中所有点坐标信息: " << endl; 24 output(x); 25 cout << "\ny对象中所有点坐标信息: " << endl; 26 output(y); 27 } 28 int main() { 29 test(); 30 }
无变化
深复制
2.实验任务2
1 #pragma once 2 #include <iostream> 3 using std::cout; 4 using std::endl; 5 class Point { 6 public: 7 Point(int x0 = 0, int y0 = 0); 8 ~Point() = default; 9 int get_x() const; 10 int get_y() const; 11 void show() const; 12 void move(int new_x, int new_y); 13 private: 14 int x, y; 15 }; 16 Point::Point(int x0, int y0) : x{ x0 }, y{ y0 } { 17 } 18 int Point::get_x() const { 19 return x; 20 } 21 int Point::get_y() const { 22 return y; 23 } 24 void Point::show() const { 25 cout << "(" << x << ", " << y << ")" << endl; 26 } 27 void Point::move(int new_x, int new_y) { 28 x = new_x; 29 y = new_y; 30 }
1 #pragma once 2 #include "point.hpp" 3 #include <cassert> 4 #include <iostream> 5 class vectorPoint { 6 public: 7 vectorPoint(int n); 8 ~vectorPoint(); 9 int get_size() const; 10 Point& at(int index); 11 Point& at(int index) const; 12 private: 13 int size; 14 Point* ptr; 15 }; 16 vectorPoint::vectorPoint(int n) : size{ n } { 17 ptr = new Point[n]; 18 } 19 vectorPoint::~vectorPoint() { 20 delete[] ptr; 21 } 22 int vectorPoint::get_size() const { 23 return size; 24 } 25 Point& vectorPoint::at(int index) { 26 assert(index >= 0 && index < size); 27 return ptr[index]; 28 } 29 Point& vectorPoint::at(int index) const { 30 assert(index >= 0 && index < size); 31 return ptr[index]; 32 }
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 void test() { 9 using namespace std; 10 int n; 11 cout << "输入vectorPoint对象中元素个数: "; 12 cin >> n; 13 vectorPoint x(n); 14 cout << "x对象中所有点坐标信息: " << endl; 15 output(x); 16 vectorPoint y(x); 17 cout << "\ny对象中所有点坐标信息: " << endl; 18 output(y); 19 cout << "\n更新x对象中点坐标信息......" << endl; 20 x.at(0).move(30, 50); 21 x.at(1).move(-1, -1); 22 cout << "x对象中所有点坐标信息: " << endl; 23 output(x); 24 cout << "\ny对象中所有点坐标信息: " << endl; 25 output(y); 26 } 27 int main() { 28 test(); 29 }
变化
浅复制
浅复制
3.实验任务3
1 #pragma once 2 3 #include "point.hpp" 4 #include <cassert> 5 #include <iostream> 6 class vectorPoint { 7 public: 8 vectorPoint(int n); 9 vectorPoint(const vectorPoint& vp); 10 ~vectorPoint(); 11 int get_size() const; // 获得当前动态数组内元素个数 12 Point& at(int index); // 返回下标为index的元素引用 13 Point& at(int index) const; // 返回下标为index的元素const引用 14 private: 15 int size; // 动态数组的大小 16 Point* ptr; 17 }; 18 vectorPoint::vectorPoint(int n) : size{ n } { 19 ptr = new Point[n]; 20 } 21 vectorPoint::vectorPoint(const vectorPoint& vp) : size{ vp.size }, ptr{ new 22 Point[size] } { 23 for (auto i = 0; i < size; ++i) 24 ptr[i] = vp.ptr[i]; 25 } 26 vectorPoint::~vectorPoint() { 27 delete[] ptr; 28 } 29 int vectorPoint::get_size() const { 30 return size; 31 } 32 Point& vectorPoint::at(int index) { 33 assert(index >= 0 && index < size); // 宏,在测试模式下工作。如果不满足条件, 34 则程序终止 35 return ptr[index]; 36 } 37 Point& vectorPoint::at(int index) const { 38 assert(index >= 0 && index < size); 39 return ptr[index]; 40 }
1 #pragma once 2 #include "point.hpp" 3 #include <cassert> 4 #include <iostream> 5 class vectorPoint { 6 public: 7 vectorPoint(int n); 8 vectorPoint(const vectorPoint& vp); 9 ~vectorPoint(); 10 int get_size() const; 11 Point& at(int index); 12 Point& at(int index) const; 13 private: 14 int size; 15 Point* ptr; 16 }; 17 vectorPoint::vectorPoint(int n) : size{ n } { 18 ptr = new Point[n]; 19 } 20 vectorPoint::vectorPoint(const vectorPoint& vp) : size{ vp.size }, ptr{ new 21 Point[size] } { 22 for (auto i = 0; i < size; ++i) 23 ptr[i] = vp.ptr[i]; 24 } 25 vectorPoint::~vectorPoint() { 26 delete[] ptr; 27 } 28 int vectorPoint::get_size() const { 29 return size; 30 } 31 Point& vectorPoint::at(int index) { 32 assert(index >= 0 && index < size); 33 return ptr[index]; 34 } 35 Point& vectorPoint::at(int index) const { 36 assert(index >= 0 && index < size); 37 return ptr[index]; 38 }
1 #include "vectorPoint.hpp" 2 #include <iostream> 3 void output(const vectorPoint& v) { 4 for (auto i = 0; i < v.get_size(); ++i) 5 v.at(i).show(); 6 } 7 void test() { 8 using namespace std; 9 int n; 10 cout << "输入vectorPoint对象中元素个数: "; 11 cin >> n; 12 vectorPoint x(n); 13 cout << "x对象中所有点坐标信息: " << endl; 14 output(x); 15 vectorPoint y(x); 16 cout << "\ny对象中所有点坐标信息: " << endl; 17 output(y); 18 cout << "\n更新x对象中点坐标信息......" << endl; 19 x.at(0).move(30, 50); 20 x.at(1).move(-1, -1); 21 cout << "x对象中所有点坐标信息: " << endl; 22 output(x); 23 cout << "\ny对象中所有点坐标信息: " << endl; 24 output(y); 25 } 26 int main() { 27 test(); 28 }
无变化
深复制
浅复制指不包含指针数据成员的类直接将对象复制给另一个对象。
深复制指在类当中有指针数据成员的时候,必须对该类所有对象初始化做深复制。深复制就是先给指针所指向的单元分配空间,然后再做其他操作。
4.实验任务4
1 #include <iostream> 2 using namespace std; 3 void swap1(int& rx, int& ry); 4 void swap2(int* px, int* py); 5 void print(int x, int y); 6 void test() { 7 int x = 3, y = 4; 8 print(x, y); 9 swap1(x, y); 10 print(x, y); 11 cout << endl; 12 x = 3, y = 4; 13 print(x, y); 14 swap2(&x, &y); 15 print(x, y); 16 } 17 int main() { 18 test(); 19 } 20 void swap1(int& rx, int& ry) { 21 int t; 22 t = rx; rx = ry; ry = t; 23 } 24 void swap2(int* px, int* py) { 25 int t; 26 t = *px; *px = *py; *py = t; 27 } 28 void print(int x, int y) { 29 std::cout << "x = " << x << ", y = " << y << "\n"; 30 }
1 #include <iostream> 2 #include <typeinfo> 3 using namespace std; 4 int main() { 5 int a; 6 int& ra = a; 7 ra = 4; 8 int* pa = &a; 9 *pa = 5; 10 cout << "&a = " << hex << &a << endl; 11 cout << "&ra = " << hex << &ra << endl; 12 cout << "&pa = " << hex << &pa << "\n\n"; 13 cout << "a = " << a << endl; 14 cout << "ra = " << a << endl; 15 cout << "pa = " << hex << pa << endl; 16 cout << "*pa = " << *pa << "\n\n"; 17 cout << "type a: " << typeid(a).name() << endl; 18 cout << "type ra: " << typeid(ra).name() << endl; 19 cout << "type pa: " << typeid(pa).name() << endl; 20 }
- 引用必须被初始化,但是不分配存储空间。指针不声明时初始化,在初始化的时候需要分配存储空间。
- 引用初始化后不能被改变,指针可以改变所指的对象。
5.实验任务5
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 (auto i = 0; i < vi.get_size(); ++i) 10 cout << vi.at(i) << ", "; 11 cout << "\b\b \n"; 12 } 13 14 void test() { 15 int n; 16 cout << "输入vectorInt对象中元素个数: "; 17 cin >> n; 18 19 vectorInt x1(n); // 构造动态int数组对象x1,包含n个元素,不对元素初始化 20 for (auto i = 0; i < n; ++i) 21 x1.at(i) = i * i; 22 cout << "vectorInt对象x1: "; 23 output(x1); 24 25 vectorInt x2(n, 42); // 构造动态int数组对象x1,包含n个元素,每个元素初始值为42 26 cout << "vectorInt对象x2: "; 27 output(x2); 28 vectorInt x3(x2); // 使用x2构造x3 29 cout << "vectorInt对象x3: "; 30 output(x3); 31 32 cout << "更新vectorInt对象x2......\n"; 33 x2.at(0) = 77; 34 x2.at(1) = -999; 35 36 cout << "vectorInt对象x2: "; 37 output(x2); 38 cout << "vectorInt对象x3: "; 39 output(x3); 40 } 41 42 int main() { 43 test(); 44 }
1 #pragma once 2 3 #include <cassert> 4 #include <iostream> 5 6 using namespace std; 7 8 class vectorInt { 9 public: 10 vectorInt(int n); 11 vectorInt(int n, int value); 12 vectorInt(const vectorInt &vi); 13 ~vectorInt(); 14 15 int get_size() const; 16 int& at(int index); 17 int& at(int index) const; 18 19 private: 20 int size; 21 int *ptr; 22 }; 23 24 vectorInt::vectorInt(int n): size{n}, ptr{new int[n]} { 25 cout << "Constructor called." << endl; 26 } 27 28 vectorInt::vectorInt(int n, int value): size{n}, ptr{new int[n]} { 29 for (auto i = 0; i < size; ++i) 30 ptr[i] = value; 31 cout << "Constructor called." << endl; 32 } 33 34 vectorInt::vectorInt(const vectorInt &vi): size{vi.size}, ptr{new int[vi.size]} { 35 for (auto i = 0; i < size; ++i) 36 ptr[i] = vi.ptr[i]; 37 cout << "Copy constructor called." << endl; 38 } 39 40 vectorInt::~vectorInt() { 41 delete[] ptr; 42 cout << "Destructor called." << endl; 43 } 44 45 int vectorInt::get_size() const { 46 return size; 47 } 48 49 int& vectorInt::at(int index) { 50 assert(index >= 0 && index < size); 51 return ptr[index]; 52 } 53 54 int& vectorInt::at(int index) const { 55 assert(index >= 0 && index < size); 56 return ptr[index]; 57 }
6.实验任务6
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 class Matrix 5 { 6 public: 7 int row, col, flag = 1; 8 vector<vector<double>> v; 9 void table(const int i, const int j) 10 { 11 cout << v[i][j] << endl; 12 } 13 friend ostream& operator<<(ostream& os, Matrix& m); 14 friend istream& operator>>(istream& is, Matrix& m); 15 Matrix& operator+=(const Matrix&); 16 Matrix& operator*=(const Matrix&); 17 Matrix& operator=(const Matrix&); 18 }; 19 20 istream& operator>>(istream& is, Matrix& m) 21 { 22 cin >> m.row >> m.col; 23 double x = 0.0; 24 vector<double> vv; 25 m.v.clear(); 26 for (int i = 0; i < m.row; i++) 27 { 28 29 vv.clear(); 30 for (int j = 0; j < m.col; j++) 31 { 32 cin >> x; 33 vv.push_back(x); 34 } 35 m.v.push_back(vv); 36 } 37 return is; 38 } 39 ostream& operator<<(ostream& os, Matrix& m) 40 { 41 if (m.flag != 0) 42 { 43 for (int i = 0; i < m.row - 1; i++) 44 { 45 for (int j = 0; j < m.col - 1; j++) 46 { 47 cout << m.v[i][j] << " "; 48 } 49 cout << m.v[i][m.col - 1] << endl; 50 } 51 for (int j = 0; j < m.col - 1; j++) 52 { 53 cout << m.v[m.row - 1][j] << " "; 54 } 55 cout << m.v[m.row - 1][m.col - 1]; 56 } 57 else 58 { 59 cout << "ERROR!"; 60 } 61 return os; 62 } 63 Matrix& Matrix:: operator+=(const Matrix& m) 64 { 65 if (row == m.row && col == m.col) 66 { 67 for (int i = 0; i < row; i++) 68 { 69 for (int j = 0; j < col; j++) 70 { 71 v[i][j] += m.v[i][j]; 72 } 73 } 74 } 75 else 76 { 77 flag = 0; 78 } 79 return *this; 80 } 81 Matrix& Matrix:: operator*=(const Matrix& m) 82 { 83 if (col == m.row) 84 { 85 for (int i = 0; i < row; i++) 86 { 87 double sum = 0; 88 for (int j = 0; j < m.col; j++) 89 { 90 for (int k = 0; k < col; k++) 91 { 92 sum += v[i][k] * m.v[k][j]; 93 } 94 v[i][j] = sum; 95 } 96 97 } 98 } 99 else 100 { 101 flag = 0; 102 } 103 return *this; 104 } 105 Matrix& Matrix::operator=(const Matrix& m) 106 { 107 flag = 1; 108 row = m.row; 109 col = m.col; 110 vector<double> vv; 111 v.clear(); 112 for (int i = 0; i < m.row; i++) 113 { 114 vv.clear(); 115 for (int j = 0; j < m.col; j++) 116 { 117 vv.push_back(m.v[i][j]); 118 } 119 v.push_back(vv); 120 } 121 return *this; 122 } 123 int main() 124 { 125 Matrix m1, m2; 126 cin >> m1 >> m2; 127 128 m1.table(m1.row / 2, m1.col / 2); 129 130 m1 *= m2; 131 cout << m1 << endl; 132 133 m1 += m2; 134 cout << m1 << endl; 135 136 m1 = m2; 137 cout << m1; 138 return 0; 139 }
1 #include <iostream> 2 #include "matrix.hpp" 3 using namespace std; 4 const int N1 = 3; 5 const int N2 = 2; 6 // 输出一个矩阵对象中索引为index对应的行的所有元素值 7 void output(const Matrix& m, int index) { 8 for (auto j = 0; j < m.get_cols(); ++j) 9 cout << m.at(index, j) << ", "; 10 cout << "\b\b \n"; 11 } 12 void test() { 13 double x[N1 * N2] = { 1, 2, 3, 4, 5, 6 }; 14 Matrix m1(N1, N2); 15 m1.set(x); 16 cout << "矩阵对象m1: " << endl; 17 m1.print(); 18 cout << "矩阵对象m1第0行是: " << endl; 19 output(m1, 0); 20 cout << endl; 21 Matrix m2(N2, N1); 22 m2.set(x); 23 cout << "矩阵对象m2: " << endl; 24 m2.print(); 25 cout << "矩阵对象m2第0行是: " << endl; 26 output(m2, 0); 27 cout << endl; 28 Matrix m3(m2); 29 m3.set(0, 0, 999); 30 cout << "矩阵对象m3:" << endl; 31 m3.print(); 32 cout << endl; 33 Matrix m4(2); 34 m4.set(x); 35 cout << "矩阵对象m4:" << endl; 36 m4.print(); 37 } 38 int main() { 39 test(); 40 }