运算符重载:对已有的运算符重新定义,赋予其另一种功能,以适应不同的数据类型 1.加号运算符重载 ①成员函数重载,用一个对象去调用另一个对象 Solution C = C1.operator+(C2)
Solutin operator+(Solution &C2)
{
Solution tmp;
tmp->a = this->a + C2->a;
return tmp;
}
②全局函数重载 Solution C = operator+(C1,C2); //C2也可以是别的函数类型,实现对象和int等类型的相加
Solutin operator+(Solution &C1, Solution &C2)
{
Solution tmp;
tmp->a = C1->a + C2->a;
return tmp;
}
2.左移运算符重载 函数重载时,为了让cout在左边,p在右边,因此无法用成员函数调用左移运算符,只能利用全局函数;
void operator<<(ostream &cout,Solution &p) //相当于operator<<(cout,p)
{
cout<<p.a<<p.b
}
链式编程:实现cout<<p<<endl;的输出写法如下:
ostream & operator<<(ostream &cout,Solution &p) //相当于operator<<(cout,p)
{
cout<<p.a<<p.b
return cout;
}
3.递增运算符重载
Solution &operator++() //返回引用是为了一直对一个数据进行操作,而不是拷贝的数据
{
a++;
return *this;
}
//int是占位参数可以用来区分前置和后置递增,后置递增,先返回;
Solution operator++(int) //此处不能返回引用,返回局部的引用,该函数结束会释放,再利用就是非法操作
{
Solution tmp = *this;
a++;
return tmp;
}
4.赋值运算符重载 赋值运算符operator=对属性进行值拷贝 对于内置的数据类型允许连等a=b=c; 赋值拷贝中如果有在堆区new一块内存,如果两个对象中有拷贝的操作,在析构函数中释放它的时候,这两个数据指向同一块内存区,释放的时候会导致堆区的内存重复释放,导致崩溃;
Solution& operator=(Solution &P)
{
//如果P里面已经有内存数据了,应该先释放干净
if(a!=NULL){
delete a;
a = NULL;
}
//编译器会提供浅拷贝
a = P.a;
//深拷贝
a = new int(*p.a);
//返回自身,需要用引用
return *this;
}
5.关系运算符重载 两个对象之间是不明确是否相等的,需要我们自己进行重载,成员函数重载 P1==P2
bool operator==(Solution &P2)
{
if(this->a==P2.a && this->b==P2.b)
return true;
return falae;
}
6.函数调用运算符重载 由于和函数调用很想,因此也叫作仿函数;
class Solution
{
public:
void operator()(string name)
{
cout<<name<<endl;
}
}
void test()
{
Solution C;
c("hello"); //调用重载函数
}
匿名函数对象:Solutin()(name); 也会调用成员函数的重载 特点:当前行执行完立即被释放
|