Cpp中数组类的实现以及操作符的重载。。
Array.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| int main() { Array a1(10); for (int i = 0; i < a1.length(); i++) { a1[i] = i; } for (int i = 0; i < a1.length(); i++) { cout << a1[i]; } cout << a1; Array a2 = a1; for (int i = 0; i < a2.length(); i++) { cout << a1[i]; } Array a3(5); a3 = a1; cout << "a3:" << a3;
if (a1 == a3) { cout << "相等" << endl; } else { cout << "不相等" << endl; }
if (a1 != a3) { cout << "不相等" << endl; } else { cout << "相等" << endl; }
return 0; }
|
重载<<函数
1 2 3 4 5 6 7 8 9
| ostream& operator<<(ostream &out, Array &obj) { for (int i = 0; i < obj.length(); i++) { out << obj[i] << " "; } return out; }
|
成员函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| 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
类中写成员函数。