第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 的内容如下
#ifndef _ARRAY_H_
#define _ARRAY_H_
class Array{
private:
enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
int data[SIZE]; //被包装的原生数组,可称之为数据的容器
int size; //当前数组的实际元素个数
public:
int getSize()const{return size;}
//默认构造函数
Array();
//拷贝构造函数
Array(const Array&rhs);
//原生数组构造函数,a表示原生数组,n表示用a中前n个元素生成对象
Array(int const a[],int n);
//填充构造函数,表示该数组由count个value构成
Array(int count,int value);
};
#endif // _ARRAY_H_
main.cpp 的内容如下
#include <iostream>
#include "Array.h"
using namespace std;
int A[] = {100,200,400,800,1600};
int main(){
Array a,b(A,5);
Array c(b),d(8,6);
cout<<a.getSize()<<" "<<b.getSize()<<" "<<c.getSize()<<" "<<d.getSize()<<endl;
return 0;
}
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 的内容如下
#ifndef _ARRAY_H_
#define _ARRAY_H_
class Array{
private:
enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
int data[SIZE]; //被包装的原生数组,可称之为数据的容器
int size; //当前数组的实际元素个数
public:
int getSize()const{return size;}
//4个构造函数
Array();
Array(const Array&rhs);
Array(int const a[],int n);
Array(int count,int value);
/**增删查改*/
//pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
void insert(int pos,int value);
//删除pos位置上的元素,其后的元素依次前移
void remove(int pos);
//返回第pos个位置上的元素值
int at(int pos)const;
//将pos位置上的元素值修改为newValue
void modify(int pos,int newValue);
//显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
void disp()const;
};
#endif // _ARRAY_H_
main.cpp 的内容如下
#include <iostream>
#include "Array.h"
using namespace std;
int main(){
int n,x;
Array a;
cin>>n;
for(int i=0;i<n;++i){
cin>>x;
a.insert(a.getSize(),x);
}
a.disp();
for(int i=0;i<3&&a.getSize()!=0;++i){
a.remove(0);
}
a.disp();
for(int i=0;i<a.getSize();i+=2){
a.modify(i,a.at(i)*10);
}
a.disp();
return 0;
}
#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 的内容如下:
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <stdexcept>
using std::invalid_argument;
using std::overflow_error;
class Array{
private:
enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
int data[SIZE]; //被包装的原生数组,可称之为数据的容器
int size; //当前数组的实际元素个数
public:
int getSize()const{return size;}
//4个构造函数
Array()throw();//这表示该函数不允许抛出任何异常
Array(const Array&rhs)throw();//同上
//以下2个构造函数有可能抛出一个invalid_argument异常
Array(int const a[],int n)throw(invalid_argument);
Array(int count,int value)throw(invalid_argument);
/**增删查改*/
//pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
//该函数有可能抛出2种异常,非法参数或者溢出,考虑一下何时会溢出
void insert(int pos,int value)throw(invalid_argument,overflow_error);
//删除pos位置上的元素,其后的元素依次前移
void remove(int pos)throw(invalid_argument);
//返回第pos个位置上的元素值
int at(int pos)const throw(invalid_argument);
//将pos位置上的元素值修改为newValue
void modify(int pos,int newValue)throw(invalid_argument);
//显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
void disp()const throw();
};
#endif // _ARRAY_H_
main.cpp 的内容如下:
#include <iostream>
#include "Array.h"
using namespace std;
int A[] = {1,23,4};
int main(){
try{
int u[7];
for(int i=0;i<7;++i)cin>>u[i];
Array a(A,u[0]);
a.disp();
Array b(u[1],9);
b.disp();
a.insert(u[2],100);
a.disp();
a.remove(u[3]);
a.disp();
cout<<a.at(u[4])<<endl;
a.modify(u[5],100);
a.disp();
if ( u[6] < 0 ){
Array c(1000,0);
c.insert(0,100);
}
}catch(exception&e){
cout<<e.what()<<endl;
}
return 0;
}
#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 a
与 Array 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 的内容如下
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <iostream>
class Array{
private:
enum {SIZE=1000};//该枚举的作用是规定原生数组的尺寸
int data[SIZE]; //被包装的原生数组,可称之为数据的容器
int size; //当前数组的实际元素个数
public:
int getSize()const{return size;}
//4个构造函数
Array();
Array(const Array&rhs);
Array(int const a[],int n);
Array(int count,int value);
/**增删查改*/
//pos位置上插入一个值为value的元素,pos及其后面的元素依次后移
void insert(int pos,int value);
//删除pos位置上的元素,其后的元素依次前移
void remove(int pos);
//返回第pos个位置上的元素值
int at(int pos)const;
//将pos位置上的元素值修改为newValue
void modify(int pos,int newValue);
//显示函数,将数组内容显示输出为一行,且每一个数后面均有一个空格
void disp()const;
//简单赋值运算符重载
Array& operator = (const Array&rhs);
//方括号运算符重载
int& operator [] (int pos);
const int& operator [] (int pos)const;
};
//小于号运算符重载
bool operator < (const Array&lhs,const Array&rhs);
//等于号运算符重载
bool operator == (const Array&lhs,const Array&rhs);
//加号运算符重载
const Array operator + (const Array&lhs,const Array&rhs);
//流输出运算符重载
using std::ostream;
ostream& operator << (ostream&os,const Array&rhs);
#endif // _ARRAY_H_
main.cpp 的内容如下
#include <iostream>
#include "Array.h"
#include <stdio.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
Array a(n,0),b(m,0);
for(int i=0;i<n;++i) cin>>a[i];
for(int i=0;i<m;++i) cin>>b[i];
cout<<a<<endl;
cout<<b<<endl;
cout<<(a==b)<<endl;
cout<<(a<b)<<endl;
Array c;
c = a = a + b;
cout<<c<<endl;
return 0;
}
#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;
}