程序设计二(面向对象)_实训9_复杂类的实现_Array类的实现(头歌)

第1关:构造函数的实现


任务描述

Array 类是一个比较复杂的类,首先需要实现其构造函数。要求用户为 Array 类提供 4 种构造函数。

相关知识

Array 类 4 种构造函数分别是:

默认构造函数

使用该函数构造出的数组对象,逻辑上是空的;

拷贝构造函数

使用该函数构造出的输出对象,逻辑上的内容应与参数一模一样;

原生输出构造函数

给定一个 C++ 的原生数组,构造出指定内容的数组对象;

填充构造函数

给定参数 n 与 value,构造出一个数组对象,其内容是 n个 value

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

该项目一共有 3 个文件,main.cpp、Array.h 和 Array.cpp。其中 main.cpp 是测试文件,Array.h 包含 Array 类的定义和成员函数声明。用户仅能修改 Array.cpp 中的内容,在其中实现 Array 的成员函数。 Array.h 的内容如下

 
  1. #ifndef _ARRAY_H_
  2. #define _ARRAY_H_
  3. class Array{
  4. private:
  5. enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
  6. int data[SIZE]; //被包装的原生数组,可称之为数据的容器
  7. int size; //当前数组的实际元素个数
  8. public:
  9. int getSize()const{return size;}
  10. //默认构造函数
  11. Array();
  12. //拷贝构造函数
  13. Array(const Array&rhs);
  14. //原生数组构造函数,a表示原生数组,n表示用a中前n个元素生成对象
  15. Array(int const a[],int n);
  16. //填充构造函数,表示该数组由count个value构成
  17. Array(int count,int value);
  18. };
  19. #endif // _ARRAY_H_

main.cpp 的内容如下

 
  1. #include <iostream>
  2. #include "Array.h"
  3. using namespace std;
  4. int A[] = {100,200,400,800,1600};
  5. int main(){
  6. Array a,b(A,5);
  7. Array c(b),d(8,6);
  8. cout<<a.getSize()<<" "<<b.getSize()<<" "<<c.getSize()<<" "<<d.getSize()<<endl;
  9. return 0;
  10. }
nclude "Array.h"

// 默认构造函数
Array::Array() {
    size = 0; // 初始化数组元素个数为0
    // 不需要显式初始化data数组,因为int类型的数组默认初始化为0
}

// 拷贝构造函数
Array::Array(const Array& rhs) {
    size = rhs.size; // 复制元素个数
    for (int i = 0; i < size; ++i) {
        data[i] = rhs.data[i]; // 复制元素
    }
}

// 原生数组构造函数
Array::Array(int const a[], int n) {
    size = (n < SIZE)?n:SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = a[i]; // 从原生数组复制元素
    }
}

// 填充构造函数
Array::Array(int count, int value) {
    size = (count < SIZE) ? count : SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = value; // 用value填充数组
    }
}

 

第2关:成员函数的实现


任务描述

Array 类实现增、删、查、改4种功能函数,同时为了显示输出,再实现一个 disp 函数,将数组内容输出到显示器。 用户仍然要自行实现上一关中的构造函数。

相关知识

Array 类 4 种构造函数分别是:

默认构造函数

使用该函数构造出的数组对象,逻辑上是空的;

拷贝构造函数

使用该函数构造出的输出对象,逻辑上的内容应与参数一模一样;

原生输出构造函数

给定一个 C++ 的原生数组,构造出指定内容的数组对象;

填充构造函数

给定参数 n 与 value,构造出一个数组对象,其内容是 n个 value

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

该项目一共有3个文件,main.cpp、Array.h 和 Array.cpp。其中 main.cpp 是测试文件,Array.h 包含 Array 类的定义和成员函数声明。用户仅能修改 Array.cpp 中的内容,在其中实现 Array 的成员函数。 提醒一下,所有序号均从 0 开始。

Array.h 的内容如下

 
  1. #ifndef _ARRAY_H_
  2. #define _ARRAY_H_
  3. class Array{
  4. private:
  5. enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
  6. int data[SIZE]; //被包装的原生数组,可称之为数据的容器
  7. int size; //当前数组的实际元素个数
  8. public:
  9. int getSize()const{return size;}
  10. //4个构造函数
  11. Array();
  12. Array(const Array&rhs);
  13. Array(int const a[],int n);
  14. Array(int count,int value);
  15. /**增删查改*/
  16. //pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
  17. void insert(int pos,int value);
  18. //删除pos位置上的元素,其后的元素依次前移
  19. void remove(int pos);
  20. //返回第pos个位置上的元素值
  21. int at(int pos)const;
  22. //将pos位置上的元素值修改为newValue
  23. void modify(int pos,int newValue);
  24. //显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
  25. void disp()const;
  26. };
  27. #endif // _ARRAY_H_

main.cpp 的内容如下

 
  1. #include <iostream>
  2. #include "Array.h"
  3. using namespace std;
  4. int main(){
  5. int n,x;
  6. Array a;
  7. cin>>n;
  8. for(int i=0;i<n;++i){
  9. cin>>x;
  10. a.insert(a.getSize(),x);
  11. }
  12. a.disp();
  13. for(int i=0;i<3&&a.getSize()!=0;++i){
  14. a.remove(0);
  15. }
  16. a.disp();
  17. for(int i=0;i<a.getSize();i+=2){
  18. a.modify(i,a.at(i)*10);
  19. }
  20. a.disp();
  21. return 0;
  22. }

 

#include"Array.h"
#include <iostream>
using namespace std;
// 默认构造函数
Array::Array() {
    size = 0; // 初始化数组元素个数为0
    // 不需要显式初始化data数组,因为int类型的数组默认初始化为0
}
// 拷贝构造函数
Array::Array(const Array& rhs) {
    size = rhs.size; // 复制元素个数
    for (int i = 0; i < size; ++i) {
        data[i] = rhs.data[i]; // 复制元素
    }
}
// 原生数组构造函数
Array::Array(int const a[], int n) {
    size = (n < SIZE) ? n : SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = a[i]; // 从原生数组复制元素
    }
}
// 填充构造函数
Array::Array(int count, int value) {
    size = (count < SIZE) ? count : SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = value; // 用value填充数组
    }
}
// 在pos位置上插入一个值为value的元素
void Array::insert(int pos, int value) {
    if (pos >= 0 && pos <= size && size < SIZE) {
        // 将pos位置后的元素后移
        for (int i = size; i > pos; --i) {
            data[i] = data[i - 1];
        }
        // 在pos位置插入新元素
        data[pos] = value;
        // 增加数组大小
        size++;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for insertion." <<endl;
    }
}

// 删除pos位置上的元素
void Array::remove(int pos) {
    if (pos >= 0 && pos < size) {
        // 将pos位置后的元素前移
        for (int i = pos; i < size - 1; ++i) {
            data[i] = data[i + 1];
        }
        // 减少数组大小
        size--;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for removal." <<endl;
    }
}

// 返回第pos个位置上的元素值
int Array::at(int pos) const {
    if (pos >= 0 && pos < size) {
        return data[pos];
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for access." << endl;
        return 0; // 返回一个错误标志或默认值
    }
}

// 将pos位置上的元素值修改为newValue
void Array::modify(int pos, int newValue) {
    if (pos >= 0 && pos < size) {
        data[pos] = newValue;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for modification." << endl;
    }
}

// 显示函数,将数组内容显示输出为一行
void Array::disp() const {
    for (int i = 0; i < size; ++i) {
        cout << data[i] << " ";
    }
    cout << endl;
}

第3关:利用异常做参数有效性检查


任务描述

异常是一种错误处理的方式,面向对象程序设计更加倾向于异常处理。不然它们造出异常这种东西又是干嘛用的呢。

相关知识

请为 Array 类的 4 个构造函数和 5 个成员函数书写异常检测,当然实际上只有 6 个函数需要抛出异常。抛出的异常所附带的消息非常简单,只需包含抛出异常的函数名即可。提示:使用__func__ 宏,或者直接用字符串。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

该项目一共有 3 个文件,main.cpp、Array.h 和 Array.cpp。其中 main.cpp 是测试文件,Array.h 包含 Array 类的定义和成员函数声明。用户仅能修改 Array.cpp 中的内容,在其中实现 Array 的成员函数。注意需要包含相应的头文件。 特别提示:仔细看 Array.h 中的文字注释

Array.h 的内容如下:

 
  1. #ifndef _ARRAY_H_
  2. #define _ARRAY_H_
  3. #include <stdexcept>
  4. using std::invalid_argument;
  5. using std::overflow_error;
  6. class Array{
  7. private:
  8. enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
  9. int data[SIZE]; //被包装的原生数组,可称之为数据的容器
  10. int size; //当前数组的实际元素个数
  11. public:
  12. int getSize()const{return size;}
  13. //4个构造函数
  14. Array()throw();//这表示该函数不允许抛出任何异常
  15. Array(const Array&rhs)throw();//同上
  16. //以下2个构造函数有可能抛出一个invalid_argument异常
  17. Array(int const a[],int n)throw(invalid_argument);
  18. Array(int count,int value)throw(invalid_argument);
  19. /**增删查改*/
  20. //pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
  21. //该函数有可能抛出2种异常,非法参数或者溢出,考虑一下何时会溢出
  22. void insert(int pos,int value)throw(invalid_argument,overflow_error);
  23. //删除pos位置上的元素,其后的元素依次前移
  24. void remove(int pos)throw(invalid_argument);
  25. //返回第pos个位置上的元素值
  26. int at(int pos)const throw(invalid_argument);
  27. //将pos位置上的元素值修改为newValue
  28. void modify(int pos,int newValue)throw(invalid_argument);
  29. //显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
  30. void disp()const throw();
  31. };
  32. #endif // _ARRAY_H_

main.cpp 的内容如下:

 
  1. #include <iostream>
  2. #include "Array.h"
  3. using namespace std;
  4. int A[] = {1,23,4};
  5. int main(){
  6. try{
  7. int u[7];
  8. for(int i=0;i<7;++i)cin>>u[i];
  9. Array a(A,u[0]);
  10. a.disp();
  11. Array b(u[1],9);
  12. b.disp();
  13. a.insert(u[2],100);
  14. a.disp();
  15. a.remove(u[3]);
  16. a.disp();
  17. cout<<a.at(u[4])<<endl;
  18. a.modify(u[5],100);
  19. a.disp();
  20. if ( u[6] < 0 ){
  21. Array c(1000,0);
  22. c.insert(0,100);
  23. }
  24. }catch(exception&e){
  25. cout<<e.what()<<endl;
  26. }
  27. return 0;
  28. }
#include "Array.h"
#include <iostream>
using namespace std;
// 默认构造函数
Array::Array() throw() {
    size = 0;
}

// 拷贝构造函数
Array::Array(const Array& rhs) throw() {
    size = rhs.size;
    for (int i = 0; i < size; ++i) {
        data[i] = rhs.data[i];
    }
}

// 原生数组构造函数
Array::Array(int const a[], int n) throw(invalid_argument) {
    if (n < 0 || n > SIZE) {
        throw invalid_argument("Invalid size for array construction.");
    }
    size = n;
    for (int i = 0; i < size; ++i) {
        data[i] = a[i];
    }
}

// 填充构造函数
Array::Array(int count, int value) throw(invalid_argument) {
    if (count < 0 || count > SIZE) {
        throw invalid_argument("Invalid count for array construction.");
    }
    size = count;
    for (int i = 0; i < size; ++i) {
        data[i] = value;
    }
}

// 在pos位置上插入一个值为value的元素
void Array::insert(int pos, int value) throw(invalid_argument, overflow_error) {
    if (pos < 0 || pos > size) {
        throw invalid_argument("Invalid position for insertion.");
    }
    if (size >= SIZE) {
        throw overflow_error("Array is full, cannot insert more elements.");
    }
    for (int i = size; i > pos; --i) {
        data[i] = data[i - 1];
    }
    data[pos] = value;
    size++;
}

// 删除pos位置上的元素
void Array::remove(int pos) throw(invalid_argument) {
    if (pos < 0 || pos >= size) {
        throw invalid_argument("Invalid position for removal.");
    }
    for (int i = pos; i < size - 1; ++i) {
        data[i] = data[i + 1];
    }
    size--;
}

// 返回第pos个位置上的元素值
int Array::at(int pos) const throw(invalid_argument) {
    if (pos < 0 || pos >= size) {
        throw invalid_argument("Invalid position for access.");
    }
    return data[pos];
}

// 将pos位置上的元素值修改为newValue
void Array::modify(int pos, int newValue) throw(invalid_argument) {
    if (pos < 0 || pos >= size) {
        throw invalid_argument("Invalid position for modification.");
    }
    data[pos] = newValue;
}

// 显示函数,将数组内容显示输出为一行
void Array::disp() const throw() {
    for (int i = 0; i < size; ++i) {
        cout << data[i] << " ";
    }
    cout << endl;
}

第4关:运算符重载


任务描述

Array 类重载以下运算符:简单赋值运算符,方括号运算符,小于号运算符,等于号运算符,加号运算符,流输出运算符。

简单赋值运算符和方括号运算符必须以成员函数形式重载,其余运算符以非成员函数形式重载。所有非成员函数都是非友元函数。

相关知识

加号运算符完成连接操作。流输出运算符进行输出,将数组输出为一行,每个数后面接一个空格。

等于号操作符返回 true 或者 false ,两个 Array 类的实例相等,当且仅当两个实例的长度相等且每一个对应的元素分别相等。

小于号操作符返回 true 或者 false,我们使用类似于字典序来比较两个 Array 实例的大小。对于Array aArray b 而言,如果 a 的第一个数小于 b 的第一个数,我们就称 a 小于 b;如果 a 的第一个数大于 b 的第一个数,我们称 a 大于 b;如果 a 的第一个数等于b的第一个数,则比较第二个数……特别的,假设 a 是较短的数组、b 是较长的数组,且 a 的所有元素与 b 前部分的对应元素分别相等,我们称 a 是小于 b 的。反过来,如果 b 是较短的数组,a 是较长的数组,且 b 的元素与 a 前部分的对应元素分别相等,我们称 a 大于 b

用户还需实现构造函数和成员函数。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

该项目一共有 3 个文件,main.cpp、Array.h 和 Array.cpp。其中 main.cpp 是测试文件,Array.h 包含 Array 类的定义和成员函数声明。用户仅能修改 Array.cpp 中的内容,在其中实现 Array 的成员函数。

Array.h 的内容如下

 
  1. #ifndef _ARRAY_H_
  2. #define _ARRAY_H_
  3. #include <iostream>
  4. class Array{
  5. private:
  6. enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
  7. int data[SIZE]; //被包装的原生数组,可称之为数据的容器
  8. int size; //当前数组的实际元素个数
  9. public:
  10. int getSize()const{return size;}
  11. //4个构造函数
  12. Array();
  13. Array(const Array&rhs);
  14. Array(int const a[],int n);
  15. Array(int count,int value);
  16. /**增删查改*/
  17. //pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
  18. void insert(int pos,int value);
  19. //删除pos位置上的元素,其后的元素依次前移
  20. void remove(int pos);
  21. //返回第pos个位置上的元素值
  22. int at(int pos)const;
  23. //将pos位置上的元素值修改为newValue
  24. void modify(int pos,int newValue);
  25. //显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
  26. void disp()const;
  27. //简单赋值运算符重载
  28. Array& operator = (const Array&rhs);
  29. //方括号运算符重载
  30. int& operator [] (int pos);
  31. const int& operator [] (int pos)const;
  32. };
  33. //小于号运算符重载
  34. bool operator < (const Array&lhs,const Array&rhs);
  35. //等于号运算符重载
  36. bool operator == (const Array&lhs,const Array&rhs);
  37. //加号运算符重载
  38. const Array operator + (const Array&lhs,const Array&rhs);
  39. //流输出运算符重载
  40. using std::ostream;
  41. ostream& operator << (ostream&os,const Array&rhs);
  42. #endif // _ARRAY_H_

main.cpp 的内容如下

 
  1. #include <iostream>
  2. #include "Array.h"
  3. #include <stdio.h>
  4. using namespace std;
  5. int main(){
  6. int n,m;
  7. cin>>n>>m;
  8. Array a(n,0),b(m,0);
  9. for(int i=0;i<n;++i) cin>>a[i];
  10. for(int i=0;i<m;++i) cin>>b[i];
  11. cout<<a<<endl;
  12. cout<<b<<endl;
  13. cout<<(a==b)<<endl;
  14. cout<<(a<b)<<endl;
  15. Array c;
  16. c = a = a + b;
  17. cout<<c<<endl;
  18. return 0;
  19. }

 

#include"Array.h"
#include <iostream>
using namespace std;
// 默认构造函数
Array::Array() {
    size = 0; // 初始化数组元素个数为0
    // 不需要显式初始化data数组,因为int类型的数组默认初始化为0
}
// 拷贝构造函数
Array::Array(const Array& rhs) {
    size = rhs.size; // 复制元素个数
    for (int i = 0; i < size; ++i) {
        data[i] = rhs.data[i]; // 复制元素
    }
}
// 原生数组构造函数
Array::Array(int const a[], int n) {
    size = (n < SIZE) ? n : SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = a[i]; // 从原生数组复制元素
    }
}
// 填充构造函数
Array::Array(int count, int value) {
    size = (count < SIZE) ? count : SIZE; // 确保不会超出数组容量
    for (int i = 0; i < size; ++i) {
        data[i] = value; // 用value填充数组
    }
}
// 在pos位置上插入一个值为value的元素
void Array::insert(int pos, int value) {
    if (pos >= 0 && pos <= size && size < SIZE) {
        // 将pos位置后的元素后移
        for (int i = size; i > pos; --i) {
            data[i] = data[i - 1];
        }
        // 在pos位置插入新元素
        data[pos] = value;
        // 增加数组大小
        size++;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for insertion." <<endl;
    }
}

// 删除pos位置上的元素
void Array::remove(int pos) {
    if (pos >= 0 && pos < size) {
        // 将pos位置后的元素前移
        for (int i = pos; i < size - 1; ++i) {
            data[i] = data[i + 1];
        }
        // 减少数组大小
        size--;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for removal." <<endl;
    }
}

// 返回第pos个位置上的元素值
int Array::at(int pos) const {
    if (pos >= 0 && pos < size) {
        return data[pos];
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for access." << endl;
        return 0; // 返回一个错误标志或默认值
    }
}

// 将pos位置上的元素值修改为newValue
void Array::modify(int pos, int newValue) {
    if (pos >= 0 && pos < size) {
        data[pos] = newValue;
    } else {
        // 可以选择抛出异常或返回错误码
        cerr << "Invalid position for modification." << endl;
    }
}

// 显示函数,将数组内容显示输出为一行
void Array::disp() const {
    for (int i = 0; i < size; ++i) {
        cout << data[i] << " ";
    }
    cout << endl;
}

// 赋值运算符重载
Array& Array::operator=(const Array& rhs) {
    if (this != &rhs) { // 避免自赋值
        size = rhs.size;
        for (int i = 0; i < size; ++i) {
            data[i] = rhs.data[i];
        }
    }
    return *this;
}

// 方括号运算符重载,用于非const对象
int& Array::operator[](int pos) {
    if (pos < 0 || pos >= size) {
        throw invalid_argument("Index out of bounds");
    }
    return data[pos];
}

// 方括号运算符重载,用于const对象
const int& Array::operator[](int pos) const {
    if (pos < 0 || pos >= size) {
        throw invalid_argument("Index out of bounds");
    }
    return data[pos];
}

// 小于运算符重载
bool operator<(const Array& lhs, const Array& rhs) {
    int minSize = lhs.size < rhs.size ? lhs.size : rhs.size;
    for (int i = 0; i < minSize; ++i) {
        if (lhs.data[i] < rhs.data[i]) return true;
        if (lhs.data[i] > rhs.data[i]) return false;
    }
    return lhs.size < rhs.size;
}

// 等于运算符重载
bool operator==(const Array& lhs, const Array& rhs) {
    if (lhs.size != rhs.size) return false;
    for (int i = 0; i < lhs.size; ++i) {
        if (lhs.data[i] != rhs.data[i]) return false;
    }
    return true;
}

// 加号运算符重载
const Array operator+(const Array& lhs, const Array& rhs) {
    Array result;
    int maxSize = lhs.size > rhs.size ? lhs.size : rhs.size;
    if (maxSize > Array::SIZE) {
        throw overflow_error("Resulting array size exceeds maximum limit");
    }
    for (int i = 0; i < maxSize; ++i) {
        int sum = 0;
        if (i < lhs.size) sum += lhs.data[i];
        if (i < rhs.size) sum += rhs.data[i];
        result.data[i] = sum;
    }
    result.size = maxSize;
    return result;
}

// 流输出运算符重载
ostream& operator<<(ostream& os, const Array& rhs) {
    for (int i = 0; i < rhs.size; ++i) {
        os << rhs.data[i];
        if (i < rhs.size - 1) os << " ";
    }
    return os;
}

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值