目录
运算符重载就是对已有的运算符进行重定义,让它可以实现更多的功能,以适应不同的数据类型
+ 加号运算符重载
class Person
{
public:
Person()
{
a = 10;
}
int a;
};
int main()
{
Person ls1;
Person ls2;
Person ls3 = ls1 + ls2;//报错
return 0;
}
当我们需要对类与类进行相加时,无法直接使用+对类名进行相加,这时就需要进行对+号的重载,赋予加号对类相加的功能;
对运算符重载需要用到关键字operator;
class Person
{
public:
Person()
{
a = 10;
}
Person operator+(Person& ls)//通过关键字operator将+就行重载
{
Person ls1;
ls1.a = this->a + ls.a;
return ls1;
}
int a;
};
int main()
{
Person ls1;
Person ls2;
Person ls3 = ls1.operator+(ls2);//使用加号重载
cout << ls3.a << endl;
return 0;
}
上面代码将加号进行重载,跟函数重载差不多,当通过Person的类使用加号,并且后面带上Person类型的值时,将调用类内部的operator+;
当然我们也可以将使用加号重载的代码直接写成加号,例如:
int main()
{
Person ls1;
Person ls2;
Person ls3 = ls1 + ls2;//也就相当于ls1.operator+(ls2)
cout << ls3.a << endl;
return 0;
}
当然也可以对 - * \ 等进行重载;
<< 左移运算符重载
class Person1
{
public:
Person1()
{
a = 10;
}
int a;
};
int main()
{
Person1 ls;
cout << ls << endl;//报错
return 0;
}
在需要输出类中的对象时,无法直接使用类名进行输出对象,这时可以重载<<符号来解决;
class Person1
{
public:
Person1()
{
a = 10;
}
int a;
};
ostream& operator<<(ostream& cout, Person1& ls)//通过关键字operator将<<就行重载
{
cout << ls.a;
return cout;
}
int main()
{
Person1 ls;
cout << ls << endl;
return 0;
}
补充:cout的类型为ostream,并且ostream全局只有一个
上面代码在类外实现了左移重载,当<<符号左边数据为operator类型右边数据为Person1类型则调用operator<<函数,在 operator<<函数中进行打印,并返回cout方便使用endl结尾;
cout << ls << endl;//调用<<重载前
cout << endl;//调用左移重载后返回cout方便进行后续操作
;
++ 增值运算符重载
需要++类中对象时,在重载++运算符后可以直接使用++类名或类名++完成;
class Person2
{
public:
Person2()
{
a = 10;
}
Person2& operator++()//前置++重载
{
this->a++;
return *this;//返回类名方便再次调用<<重载
}
Person2 operator++(int)//后置++重载,使用int占位来重载operator++
{
Person2 ls = *this;//备份一份this的数据,方便返回++前的值
this->a++;
return ls;//返回类名方便再次调用<<重载
}
int a;
};
ostream& operator<<(ostream& cout, Person2 ls)//重载<<符号方便打印
{
cout << ls.a;
return cout;
}
int main()
{
Person2 ls;
cout << ++ls << endl;
cout << ls++ << endl;
return 0;
}
;
= 赋值运算重载
类会默认添加一个赋值运算重载operator=,用来进行值拷贝,此时如果类中有属性指向堆区,做赋值操作时就会出现深浅拷贝问题,我们可以自己实现一个能够对堆区数据进行拷贝的=重载来避免深浅拷贝问题发生;
class Person3
{
public:
Person3(int a)
{
this->a = new int(a);
}
~Person3()
{
delete a;
}
Person3& operator=(Person3& ls)// = 赋值运算重载
{
if (this->a != NULL)//判断a是否已经有一块堆区空间
{
delete a;
a = NULL;
}
this->a = new int(*ls.a);//开辟一块新的内存空间给a
return *this;//返回this方便后续操作
}
int* a;
};
ostream& operator<<(ostream& cout, Person3& ls)//重载<<符号方便打印
{
cout << *ls.a;
return cout;
}
int main()
{
Person3 ls1(10);
Person3 ls2(20);
Person3 ls3(30);
ls3 = ls1 = ls2;
cout << ls3 << endl;
return 0;
}
;
== != 关系运算符重载
重载关系运算符可以使两个自定义类型对象进行对比操作;
class Person4
{
public:
Person4(int a)
{
this->a = a;
}
bool operator==(Person4 ss)// == 关系运算符重载
{
if (this->a == ss.a)
{
return true;
}
return false;
}
bool operator!=(Person4 ss)// != 关系运算符重载
{
if (this->a == ss.a)
{
return false;
}
return true;
}
int a;
};
int main()
{
Person4 ls1(10);
Person4 ls2(20);
if (ls1 == ls2)
{
cout << "相等" << endl;
}
else if(ls1 != ls2)
{
cout << "不相等" << endl;
}
return 0;
}
;
() 函数调用运算符重载
对()进行重载来适应更多类型,由于重载后使用的方式非常像函数的调用,因此称为仿函数,仿函数没有固定写法,非常灵活
class Person5
{
public:
void operator()(string a)// () 函数调用运算符重载
{
cout << a;
}
};
void main()
{
Person5 ls;
ls("张三");
}