今天早上学妹问我一道习题让我帮她看看:
class Array{
int length;
int *arr;
public:
Array(int *a, int len);
~Array();
}
//main()
int a[]={1,2,3};
Array Arr1(&a[0],3);
Array Arr2 = -Arr1 + 6*Arr1;
cout<<Arr1<<Arr2;
我一看,就是运算符重载嘛。一通操作之后,虽然弄出来了(放在最后),但是发现有些概念很是模糊,比如参数个数怎么确定,什么时候返回引用等等。回过头来还是记录一下。
C++ Tutorials
类是C++中定义的新类型,不仅可以构造和赋值,还可以使用操作符,就像普通类型那样:int a,b;int c = a + b;。此处,使用加法运算符将两个int型变量相加,然后赋值给c。如果变为类类型,则需要重载相应的运算符。C++允许重载大多数运算符,列表如下:
和普通函数一样,重载的运算符函数也有返回值、函数参数等,但函数名为operator关键字加运算符,语法格式为:type operator sign(parameters){}。几乎所有运算符重载都可以以成员函数版本实现,但部分运算符应该使用非成员函数版本实现。
例如,流输出运算符(<<)常通常使用友元方式重载:friend ostream& operator << (ostream& os, Array& target);。之所以使用友元,其一是为了符合输出时常用的cout<<惯用形式,即流输出运算符左侧应该是ostream对象,故不能以成员函数方式进行重载,而是使用类外普通函数形式。二是在类外要访问到Array类的私有数据成员,所以使用友元函数。
结果和总结
class Array{
int length;
int *arr;
public:
Array(int *a,int len){
length = len;
arr = new int[len];
for(int i=0;i<length;++i){
arr[i] = a[i];
}
}
~Array(){delete []arr;}
Array() = default;
//copy
Array(const Array &a){
length = a.length;
arr = new int[length];
for(int i=0;i<length;++i){
arr[i]=a[i];
}
}
//copy assign
Array& operator = (const Array &a){
if(this!=&a){
if(length!=a.length){
delete []arr;
length = a.length;
arr = new int[length];
}
for(int i=0;i<length;i++){
arr[i]=a.arr[i];
}
}
return *this;
}
//+
Array operator + (const Array &a){
Array tmp;
tmp.length = a.length;
tmp.arr = new int[tmp.length];
for(int i=0;i<tmp.length;++i){
tmp.arr[i]=arr[i]+a.arr[i];
}
return tmp;
}
//-
Array operator - (){
Array tmp;
tmp.length = a.length;
tmp.arr = new int[tmp.length];
for(int i=0;i<tmp.length;++i){
tmp.arr[i]=-arr[i];
}
return tmp;
}
//*
Array operator * (int factor){
Array tmp;
tmp.length = length;
tmp.arr = new int[tmp.length];
for(int i=0;i<tmp.length;++i){
tmp.arr[i] = factor*arr[i];
}
return tmp;
}
friend Array operator * (int factor,Array &a){
Array tmp = a.operator*(factor);
return tmp;
}
//<<
friend ostream& operator << (ostream &os, const Array &a){
for(int i=0;i<a.length;++i){
os<<a.arr[i]<<" ";
}
os<<endl;
return os;
}
}
可以发现,如果是以成员函数形式重载,则需要的参数个数会少一个,因此类隐藏了其成员函数中的第一个参数this。另外,为*运算符实现了两种版本的重载,是为了满足int*Array和Array*int这两种形式的运算。
其实理解运算符重载很容易,只是因为类中有时候会涉及到静态数据、动态数据等,导致编写代码时需要特别注意一下。