一. 运算符重载
对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
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;
cout<<"m_A:"<<p3.m_A<<"m_B:"<<p3.m_B<<endl;
Person p4=p3+10;
cout<<...<<endl;
}
int main()
{
... ...
}
总结1: 对于内置的数据类型的表达式的运算符是不可能改变的 总结2:不能滥用运算符重载(例如operator+函数中写成减法)
2. 左移运算符重载
作用:可以输出自定义数据类型
class Person
{
friend ostream & operator <<(ostream & out ,Person &p);
public:
Person(int a,int b)
{
this->m_A = a;
this->m_B = b;
}
private: int m_A;
int m_B;
};
ostream & operator << (ostream &out,Person &p)
{
out<<"a:"<<p.m_A<<"b:"<<p.m_B;
return out;
}
void test()
{
Person p1(10,20);
cout<<p1<<"hello"<<endl;
}
int main()
{
... ...
}
总结:重载左移运算符配合友元可以实现输出自定义数据类型
3. 递增运算符重载
int a=10;
cout<<++a<<endl;
cout<<a<<endl;
int b=10;
cout<<b++<<endl;
cout<<b<<endl;
int main()
{
int a=10;
a++;
cout<<a<<endl;
int b=10;
++b;
cout<<b<<endl;
int a2=10;
int b2=++a2*10;
cout<<a2<<endl;
cout<<b2<<endl;
int a3=10;
int b3=a3++*10;
cout<<a3<<endl;
cout<<b3<<endl;
}
class MyInteger
{
friend ostream& operator <<(ostream& out,MyInteger myint);
public:
MyInteger()
{
m_Num=0;
}
MyInteger & operator++()
{
m_Num++;
return *this;
}
MyInteger operator++(int)
{
MyInteger temp=*this;
m_Num++;
return temp;
}
private:
int m_Num;
};
ostream & operator <<(ostream &out,MyInteger myint)
{
out<<myint.m_Num;
return out;
}
void test01()
{
MyInteger myint;
cout<<++myInt<<endl;
cout<<myInt<<endl;
}
后置++,先返回,再++
void test02()
{
MyInteger myInt;
cout<<myInt++<<endl;
cout<<myInt<<endl;
}
int main() {... ...}
总结:前置递增返回引用,后置递增返回值
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= 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<<endl;
cout<<"p2的年龄为:"<<*p2.m_Age<<endl;
cout<<"p3的年龄为:"<<*p3.m_Age<<endl;
}
int main()
{... ...}
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<<test<<endl;
}
};
void test01()
{
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="<<ret<<endl;
cout<<Myadd()(100,100)<<endl;
}
int main() {... ...}
|