对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
1. 加号运算符重载作用:实现两个自定义数据类型相加的运算
class Person
{
public:
Person(){};
Person(int a,int b)
{
this->m_A=a;
this->m_B=b;
}
//成员函数实现加号运算符重载
Person operator+ (const Person &p)
{
Person temp;
temp.m_A=this->m_A+p.m_A;
temp.m_B=this->m_B+p.m_B;
return temp;
}
public:
int m_A;
int m_B;
};
//全局函数实现加号运算符重载
Person operator+ (const Person &p1 ,const Person &p2)
{
Person temp(0,0);
temp.m_A=p1.m_A+p2.m_A;
temp.m_B=p1.m_B+p2.m_B;
return temp;
}
//运算符重载可以发生函数重载
Person operator+ (const Person p2,int val)
{
Person temp;
temp.m_A=p2.m_A+val;
temp.m_B=p2.m_B+val;
return temp;
}
void test()
{
Person p1(10,10);
Person p2(20,20);
// 成员函数方式
Person p3=p1+p2;//相当于p2.operator+(p1)
cout<<"m_A:"<
... ...
}
总结1: 对于内置的数据类型的表达式的运算符是不可能改变的
总结2:不能滥用运算符重载(例如operator+函数中写成减法)
作用:可以输出自定义数据类型
class Person
{
friend ostream & operator <<(ostream & out ,Person &p);
public:
Person(int a,int b)
{
this->m_A = a;
this->m_B = b;
}
//成员函数实现不了, p<
out<<"a:"<
Person p1(10,20);
cout<
... ...
}
总结:重载左移运算符配合友元可以实现输出自定义数据类型
3. 递增运算符重载int a=10; cout<<++a<//前置递增与后置递增的区别 int main() { int a=10; a++; //等价于a=a+1 cout<class MyInteger { friend ostream& operator <<(ostream& out,MyInteger myint); public: MyInteger() { m_Num=0; } //前置++ MyInteger & operator++() { //先++ m_Num++; //再返回 return *this; } //后置++ MyInteger operator++(int) { //int代表占位参数,可以用于区分前置和后置递增 //先记录当时结果,后递增,最后将记录结果做返回 MyInteger temp=*this; m_Num++; return temp; } private: int m_Num; }; ostream & operator <<(ostream &out,MyInteger myint) { out<MyInteger myint; cout<<++myInt< MyInteger myInt; cout< ... ...} 总结:前置递增返回引用,后置递增返回值
4. 赋值运算符重载C++编译器至少给一个类添加4个函数
1)默认构造函数(无参,函数体为空)
2)默认析构函数(无参,函数体为空)
3)默认拷贝构造函数,对属性进行值拷贝
4)赋值运算符operator=,对属性进行值拷贝如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
class Person { public: Person (int age) { //将年龄数据开辟到堆区 m_Age= new int(age); } //重载赋值运算符 Person & operator =(Person &p) { if(m_Age!=NULL) //先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝 { delete m_Age; m_Age=NULL; } //编译器提供的代码是浅拷贝 即m_Age=p.m_Age; //提供深拷贝,解决浅拷贝的问题 m_Age= new int(*p.m_Age); //返回自身 return *this; } ~Person() { if(m_Age!=NULL) { delete m_Age; m_Age=NULL; } } //年龄的指针 int *m_Age; } void test01() { Person p2(20); Person p3(30); p3=p2=p1; //赋值操作 cout<<"p1的年龄为:"<<*p1.m_Age<5. 关系运算符重载... ...} 作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
bool operator ==(Person &p) { if(this->m_Nane==p.m_Name && this->m_Age==p.m_Age) { return true; } else { return false; } } bool operator !=(Person &p) { if(this->m_Nane==p.m_Name && this->m_Age==p.m_Age) { return false; } else { return true; } }6. 函数调用运算符重载1)函数调用运算符()也可以重载
2)由于重载后使用的方式非常向函数的调用,因此称为仿函数
3)仿函数没有固定写法,非常灵活class Myprint { public: void operator()(string test) { cout<//重载()操作符也称为仿函数 Myprint myFunc; myFunc("hello"); } class Myadd { public: int operator()(int v1,int v2) { return v1+v2; } }; void test02() { Myadd add; int ret=add(10,10) cout<<"ret="< ... ...}



