C++/Array类的实例

//头文件/Array.h

/*Array.h*/
#pragma once
#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
/**/
class Array
{
	/*友元函数,重载流插入、流提取运算符*/
	/*1、用户自定义的类型的数据,要使用流插入"<<"和流提取">>"必须进行重载
	2、流插入,流提取只能重载为全局函数,不能重载为成员函数*/
	
	/*1、重载为友元函数,参数的个数等于操作数个数;重载为成员函数时,参数个数等于操作数减1	
	2、返回值类型为引用,支持级联调用	3、第一个参数为ostream类的引用,第二个参数为
	Array类的引用(如果不使用引用,改为传参则会调用拷贝构造函数,增加开销),加const是因为流提取,输出内容,不需要更改*/
	friend std::ostream &operator<<(std::ostream &, const Array&);
	/*重载流提取,第一个参数为istream类的引用,第二个参数为Array类的引用(避免调用拷贝构造函数),
	流提取需要输入内容,所以不加const*/
	friend std::istream &operator>>(std::istream &, Array &);

public:
	/*1、默认构造函数,单参,使用explicit避免隐式的类型转换
	2、使用了默认参数*/
	explicit Array(int = 10);
	/*转换构造函数:1、作用:实现类型的自动转换	 2、判断:一般满足1.单参构造函数,
	2.不是拷贝构造函数 即为转换构造函数	 3、运行原理:当需要时,系统自动调用,并建立一个无名的临时对象(或变量)
	3、使用引用参数,避免使用值传递,从而造成无限拷贝*/
	Array(const Array &);
	/*析构函数*/
	~Array();
	/*获取数组大小*/
	size_t getSize() const;
	
	/*1、重载赋值运算符	 2、重载为成员函数,参数的个数等于操作数个数减一*/
	const Array& operator=(const Array&);
	/*重载判断是否相等的运算符*/
	bool operator==(const Array&) const;
	/*重载不等运算符*/
	bool operator!=(const Array& right) const
	{
		return !(*this == right);
	}
	
	/*重载[]运算符*/
	int &operator[](int);

	/*重载[]运算符*/
	int operator[](int) const;
private:
	/*size_t是一种无符号的整型数,它的取值没有负数,取值范围是整型数的双倍*/
	size_t size;
	/*定义一个整型指针*/
	int* ptr;

};

#endif // !1



源文件/Array.cpp

/*Array.cpp*/
#include "Array.h"
#include <iostream>
#include <iomanip>
#include <stdexcept>

using namespace std;
Array::Array(int arraySize)
	/*判断参数的有效性,满足条件则为私有成员size赋值,否则抛出异常提示*/
	: size(arraySize > 0 ? arraySize :
		throw invalid_argument("Array size must be greater than 0")),
	/*使用new运算符动态创建长度为int的整型数组,并将数组的首地址赋值给Array类的私有
	成员整型指针ptr*/
		ptr(new int[size])
	{/*使用for循环,将数组的所有元素初始化为0*/
		for (size_t i = 0; i < size; ++i) {
			ptr[i] = 0;
		}
	}

/*1、使用引用,避免值传递造成无限调用拷贝函数  2、加const,因为无需修改参数的值*/
Array::Array(const Array& arrayToCopy)
	/*将引用对象的size值赋值给私有成员size*/
	:size(arrayToCopy.size),
	/*使用new运算符动态创建一个长为size的整型数组,并将数组的首地址赋值为私有成员
	整型指针ptr*/
	
	ptr(new int[size])
{	/*使用for循环对所有数据元素初始化为0*/
	for (size_t i = 0; i < size; ++i) {
		/*这里使用了数据赋值的方式*/
		ptr[i] = arrayToCopy.ptr[i];
	}
}

Array::~Array()
{	/*使用delete释放数组内存空间,一定要加下标运算符[],否则只会释放数组的第一个元素*/
	delete[] ptr;
}

/*获取数组长度大小*/
size_t Array::getSize() const
{
	return size;
}

/*1、重载赋值运算符
2、参数为Array的引用(避免使用值传递,调用拷贝构造函数从而增加开销)
3、参数使用const,参数不需要修改,避免参数被修改	4、函数返回值为const Array引用
使用引用是为了支持级联调用,使用const是为了防止(a=b)=c即作为左值这种情况的发生*/
const Array& Array::operator=(const Array& right)
{	/*判断引用的参数是否为当前对象,避免自我复制*/
	if (&right != this)
	{	/*当前对象的size值不等于引用对象的size值时*/
		if (size != right.size) {
			/*释放ptr所指的全部内容*/
			delete[] ptr;
			/*将当前对象的size值赋值为引用对象的size值*/
			size = right.size;
			/*用运算符new动态创建一个长为size的整型数组,并由Array类的私有成员
			整型指针ptr指向数组的首地址*/
			ptr = new int[size];
		}
		/*使用for循环将数组的所有元素初始化为0*/
		for (size_t i = 0; i < size; ++i) {
			ptr[i] = right.ptr[i];
		}
	}
	/*返回当前对象的const引用*/
	return *this;
}

/*常量对象,常量成员函数,常引用:
1、常量对象:const Demo obj; //对象obj的值不能被修改
2、常量成员函数:在函数后面加const关键字,
不能修改其作用的对象(对象的数据成员不能被修改),也不能调用同类的非常量成员函数(因为同类的非常量成员函数可能会修改其作用的对象)
(静态成员变量和静态成员函数除外(静态的为所有对象所共有))
可以重载:int f() const;   int f();
3、常引用:使用对象的引用作为参数,避免值传递导致拷贝构造函数被调用,从而增加开销。加上const防止引用修改了实参,
这样既高效又安全*/



/*1、重载是否相等的运算符	2、*/ 
bool Array::operator==(const Array& right) const {
	if (size != right.size) {
		return false;
	}

	for (size_t i = 0; i < size; ++i) {
		if (ptr[i] != right.ptr[i]) {
			return false;
		}
		return true;
	}

}

int & Array::operator[](int subscript) {
	if (subscript < 0 || subscript >= size) {
		throw out_of_range( "Subscript out of range");
	}
	return ptr[subscript];
}

int Array::operator[](int subscript) const {
	if (subscript < 0 || subscript >= size) {
		throw out_of_range("Subscript out of range ");
	}
	return ptr[subscript];
}

istream& operator>>(istream& input, Array& a) {
	for (size_t i = 0; i < a.size; ++i) {
		input >> a.ptr[i];
	}
	return input;
}

ostream& operator<<(ostream& output, const Array& a) {
	for (size_t i = 0; i < a.size; ++i) {
		output << setw(12) << a.ptr[i];
		if ((i + 1) % 4 == 0) {
			output << endl;
		}
	}

	/*每次输出4个元素,然后进行换行*/
	if (a.size % 4 != 0) {
		output << endl;
	}

	return output;
}

测试程序/main.cpp

/*main.cpp*/
#include <iostream> 
#include <stdexcept>
#include "Array.h"
using namespace std;

int main() {
	
	Array integers1(7);
	Array integers2;

	cout << "Size of Array integers1 is "
		<< integers1.getSize()
		<< "\nArray after initialization:\n"
		<< integers1;

	cout << "\nSize of Array integers2 is "
		<< integers2.getSize()
		<< "\nArray after initialization :\n"
		<< integers2;

	cout << "\nEnter 17 integers: "
		<< endl;

	cin >> integers1 >> integers2;

	cout << "\nAfter input , the Arrays contain :\n"
		<< "integers1:\n" << integers1
		<< "integers2:\n" << integers2;

	cout << "\nEvaluating: integers1 != integers2 " << endl;

	integers1 = integers2;

	cout << "integers1:\n" << integers1
		<< "integers2:\n" << integers2;

	cout << "\nEvaluating: integers1 == integers2" << endl;

	if (integers1 == integers2) {
		cout << "integers1 and integers2 are equal" << endl;
	}

	cout << "\nintegers1[5] is " << integers1[5];

	cout << "\n\nAssigning 1000 to integers1[5]" << endl; 
	integers1[5] = 1000;

	cout << "integers1:\n" << integers1;

	try {
		cout << "\nAttemp to assign 1000 to integers1[15]" << endl;
		integers1[15] = 1000;
	}
	catch (out_of_range& ex) {
		cout << "An exception occurred: " << ex.what() << endl;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值