Cpp中数组类的实现以及操作符的重载。
Array.h
#pragma once
class Array
{
public:
int mLength;
int* mSpace;
public:
Array(int length);
Array(const Array& obj);
int& operator[](int i);
Array& operator=(Array &obj);
bool operator==(Array &obj);
bool operator!=(Array &obj);
int length();
void setData(int index, int value);
int getData(int index);
~Array();
};
main.c
int main()
{
//定义一个Array类型的啊对象并调用Array类的有参构造函数
Array a1(10);
//对数组的元素进行初始化
for (int i = 0; i < a1.length(); i++)
{
//a1.setData(i, i); //初步
a1[i] = i; //提升 []重载
}
//对数组的元素进行输出
for (int i = 0; i < a1.length(); i++)
{
//printf("array %d: %d\n", i, a1.getData(i)); //初步
cout << a1[i];
}
cout << a1; // <<重载
//用a1对象初始化a2对象,调用a2对象的拷贝构造函数
//总结1
Array a2 = a1;
for (int i = 0; i < a2.length(); i++)
{
//printf("array %d: %d\n", i, a2.getData(i));
cout << a1[i];
}
Array a3(5);
a3 = a1; //c++编译器提供的等号操作符为浅拷贝需重载 =
//总结2
cout << "a3:" << a3;
if (a1 == a3)
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
if (a1 != a3)
{
cout << "不相等" << endl;
}
else
{
cout << "相等" << endl;
}
return 0;
}
重载<<函数
ostream& operator<<(ostream &out, Array &obj)
{
for (int i = 0; i < obj.length(); i++)
{
//out << obj.mSpace[i] << " ";
out << obj[i] << " ";
}
return out;
}
成员函数实现
Array::Array(int length)
{
mLength = length;
mSpace = new int[mLength];
}
Array::Array(const Array& obj)
{
mLength = obj.mLength;
mSpace = new int [mLength];
for (int i = 0; i < mLength; i++)
{
mSpace[i] = obj.mSpace[i];
}
}
int Array::length()
{
return mLength;
}
void Array::setData(int index, int value)
{
mSpace[index] = value;
}
int Array::getData(int index)
{
return mSpace[index];
}
Array::~Array()
{
delete[] mSpace;
mSpace = NULL;
mLength = 0;
}
int& Array::operator[](int i)
{
return this->mSpace[i];
}
Array& Array::operator=(Array &obj)
{
delete[] this->mSpace;
this->mLength = 0;
this->mLength = obj.mLength;
this->mSpace = new int[mLength];
for (int i = 0; i < mLength; i++)
{
mSpace[i] = obj[i];
}
return *this;
}
bool Array::operator==(Array &obj)
{
if (this->mLength != obj.mLength)
{
return false;
}
for (int i = 0; i < mLength; i++)
{
if (mSpace[i] != obj[i])
{
return false;
}
}
return true;
}
bool Array::operator!=(Array &obj)
{
return !(*this == obj);
}
总结:
拷贝构造函数的四种调用方法:
1.Array a1(a2);
2.Array a1 = a2;
3.函数调用过程中,例如:main
函数中调用f
函数f(a1);
,其中a1
为Array
类型的一个对象,f
函数的声明为void f(Array a);
这时函数的调用过程中会调用a
对象的拷贝构造函数。
4.被调用函数的返回值是一个对象的时候,这时c++
编译器会创建一个匿名对象,然后调用匿名对象的拷贝构造函数。而这个匿名对象的生命周期取决于主调用函数的接法,如果是类的初始化那么匿名对象转正,直到程序运行完成时才会调用析构函数,若是类的赋值,则在赋值完以后立马调用匿名对象的析构函数。
重载<<
C++Primer第六页中说,<<运算符接受两个运算对象:左侧的运算对象必须是一个ostream
对象(也就是说cout
是一个ostream
类型的对象),右侧的运算对象是要打印的值。
使用过程中我们的输出语句可以使用多次<<运算符,因此<<运算符返回其左侧的运算对象(即ostream类型),这样才能保证第一次的运算结果能作为第二次<<运算符的左侧运算对象。有了这个前提之后我们在写<<运算符重载函数的时候,函数应返回本身(即返回一个引用),因此函数的声明应为ostream& operator<<(ostream &out, Array &obj)
。
运算符重载函数可以为全局函数也可以为成员函数,大部分情况下二者可以相互转换,以二元运算符为例,全局函数需要两个参数,左操作数与右操作数,而成员函数可通过this
指针“隐藏”一个参数。但也有例外,在重载<<时必须使用成员函数,因为我们不能进入到ostream
类中写成员函数。