运算符重载:
对已有的运算符进行重新定义,赋予其另一种功能,以适应不同的数据类型。
1.加号运算符重载:
分为 成员函数重载 和 全局函数重载。
有一个Person类:
class Person
{
public:
int A;
int B;
};
定义两个对象:
Person p1;
p1.A = 10;
p1.B = 10;
Person p2;
p2.A = 20;
p2.B = 20;
写一个成员函数让两个对象中的值对应相加,再返回一个新的对象:
Person personadd(Person p)
{
Person ret;
ret.A = this->A + p.A;
ret.B = this->B + p.B;
return ret;
}
再将函数名换为编译器给好的名称:operator运算符
//成员函数重载
Person operator+(Person p)
{
Person ret;
ret.A = this->A + p.A;
ret.B = this->B + p.B;
return ret;
}
//全局函数重载
Person operator+(Person& p1, Person& p2)
{
Person ret;
ret.A = p1.A + p2.A;
ret.B = p1.B + p2.B;
return ret;
}
即可将 Person p3 = p1.operator+(p2) 或 Person p3 = operator+( p1 , p2 )
化简为 Person p3 = p1 + p2;
注:运算符重载也可以发生函数重载。
2.左移运算符重载:
即输出时的 << 运算符(cout << endl;)
注:通常不用成员函数重载左移运算符,因为此函数需要通过对象调用,故对象名在左,无法使 cout 在左面。
用全局函数重载:
class Person
{
public:
int A;
int B;
};
ostream& operator<<(ostream& cout, Person& p)
{
cout << p.A << "," << p.B;
return cout;
}
注意:1.此函数本质为operator<<(cout , p),简化为 cout << p
2.重点!!返回值设为 ostream ,因为重新将 cout 返回,即可连续输出,
即cout << p1 << p2 << endl;
3.递增运算符重载:
即 “ ++ ” 运算符,分为前置和后置。
class MyInteger
{
public:
MyInteger()
{
m_Num = 0;
}
int m_Num;
};
(1)前置++:返回引用
//重载前置++
MyInteger& operator++()
{
m_Num++;
return *this;
}
(2)后置++:返回值
重点!!此时需要再参数列表中加上一个 int 作为占位参数,以区分前置后置,且只能为 int 。
//重载后置++
MyInteger operator++(int)
{
MyInteger ret = *this;
this->m_Num++;
return ret;
}
4.赋值运算符重载:
即“ = ”运算符。
先写一个类:
class Person
{
public:
Person(int age)
{
m_age = new int(age);
}
~Person()
{
if (this->m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
int* m_age;
};
然后再进行赋值:
int main()
{
Person p1(18);
Person p2(20);
p2 = p1;
return 0;
}
这样程序会崩溃,其实依旧为深浅拷贝的问题:
解决方法:重载赋值运算符:
Person& operator=(Person& p)
{
//如果m_age不为空,就释放干净
if (m_age != NULL)
{
delete m_age;
}
//再重新申请内存
this->m_age = new int(*p.m_age);
return *this;
}
5.关系运算符重载:
重载关系运算符(即“==”,“!=”),可以让两个自定义类型对象进行对比。
定义一个类:
class Person
{
public:
Person(int age)
{
this->age = age;
}
int age;
};
重载“==”和“!=”
//重载==
bool operator==(Person& p)
{
if (this->age == p.age)
return true;
else return false;
}
//重载!=
bool operator!=(Person& p)
{
if (this->age != p.age)
return true;
else return false;
}
6.函数调用运算符重载:
函数调用运算符重载(即“()”),使用的方式类似函数的调用,又名仿函数。
class MyPrint
{
public:
//重载函数调用运算符
void operator()(string str)
{
cout << str << endl;
}
};
void print(string str)
{
cout << str << endl;
}
int main()
{
MyPrint p;
p("hello world");//仿函数
print("hello world");//函数
}
注:匿名函数对象:类名加(),如 Person( )
这个创建的对象没有名字,且执行完当行的任务后立即释放。
例:如利用上面的例子:
MyPrint()("hello world");
即可输出“hello world”