运算符重载就是对已有的运算符重新定义,使其适应不同数据类型的运算
运算符重载也可以发生函数重载,例如可以将类与类相加或者类中某变量与一个整型相加
友元函数重载时,参数列表为1,说明是1元,为2说明是2元
成员函数重载时,参数列表为空,是一元,参数列表是1,为2元
1.加号运算符的重载(举例实现类的对象的相加减)
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
public:
int m_A;
int m_B;
Person operator+ (Person &p) //1.通过成员函数来实现
{
Person tmp;
tmp.m_A = this->m_A + p.m_A;
tmp.m_B = this->m_B + p.m_B;
return tmp;
}
};
Person operator+ (Person &p1, Person &p2) //2.通过全局函数来重载
{
Person tmp;
tmp.m_A = p2.m_A + p1.m_A;
tmp.m_B = p2.m_B + p1.m_B;
return tmp;
}
Person operator+ (Person &p1, int num) //作函数重载,类与整型
{
Person tmp;
tmp.m_A = num + p1.m_A;
tmp.m_B = num + p1.m_B;
return tmp;
}
void test()
{
Person p1;
p1.m_A = 10;
p1.m_B = 10;
Person p2;
p2.m_A = 10;
p2.m_B = 10;
Person p3 = p1 + p2; //重载之后可以直接相加减
cout << "p3.m_A = " << p3.m_A << endl;
cout << "p3.m_B = " << p3.m_B << endl;
Person p4 = p1 + 100; //类与整型相加
cout << "p4.m_A = " << p4.m_A << endl;
cout << "p4.m_B = " << p4.m_B << endl;
}
int main(void)
{
test();
}
2.左移运算符的重载,一般不会使用成员函数重载,因为函数调用时格式为p << cout,这样无法实现cout 在右边的通俗写法,因此再用全局函数。
可以输出自定义的数据类型,举例输出类中的变量值
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
// friend ostream& operator<< (ostream &cout, Person &p);如果要访问的是私有类型数据,可以将重载
//函数变成友元类型,并写一个构造函数来初始化
public:
int m_A;
int m_B;
};
ostream& operator<< (ostream &cout, Person &p) //cout是ostream流类型
{
cout << "m_A = " << p.m_A << endl;
cout << "m_B = " << p.m_B; //这里不加换行是为了格式与正常使用cout和endl时一样
return cout;
}
void test()
{
Person p3;
p3.m_A = 10;
p3.m_B = 10;
cout << p3 << endl;
}
int main(void)
{
test();
}
3.递增运算符的重载(分为前++和后++)
#include <iostream>
#include <string.h>
using namespace std;
class MyInteger
{
friend ostream& operator<< (ostream &cout, MyInteger myint); //操作私有变量设置为友元
public:
MyInteger& operator++ () //前++,返回&是为了操作同一个数,否则后面继续操作时数字
//仍是++前的值,只是打印出了++后的结果,值并没有发生变化
{
m_Num++;
return *this;
}
MyInteger operator++(int) //后++,int代表占位参数,区分前后++,返回值是因为tmp在结
//束后就会被销毁
{
MyInteger tmp = *this; //这里先返回当前值的结果,再做递增
m_Num++;
return tmp;
}
MyInteger()
{
m_Num = 0;
}
private:
int m_Num;
};
ostream& operator<< (ostream &cout, MyInteger myint) //输出自己定义的数据类型先做左移重载
{
cout << myint.m_Num;
return cout;
}
void test1()
{
MyInteger myint;
cout << ++myint << endl;
cout << myint << endl;
}
void test2()
{
MyInteger myint;
cout << myint++ << endl;
cout << myint << endl;
}
int main(void)
{
test1();
test2();
}
4.赋值运算符的重载(当类中有指针变量时涉及到深浅拷贝的问题,应此重载一个函数)
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
public:
int *age;
Person(int age)
{
this->age = new int(age);
}
~Person()
{
if(age != NULL)
{
delete age;
age = NULL;
}
}
Person& operator= (Person &p)
{
//age = p.age 这个是编译器做的浅拷贝
if(age != NULL) //如果P2已经初始化了,先释放空间,判断的是左边的变量
{
delete age;
age = NULL;
}
age = new int(*p.age); //实现的深拷贝
return *this; //实现p3 = p2 = p1的连续操作
}
};
void test()
{
Person p1(10);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
cout << "age = " << *p1.age << endl;
cout << "age = " << *p2.age << endl;
cout << "age = " << *p3.age << endl;
}
int main(void)
{
test();
}
5.关系运算符的重载(举例是==的重载,相同方法可以重载其他类型的运算符)
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
public:
string name;
int age;
Person(string name, int age)
{
this->name = name;
this->age = age;
}
bool operator== (Person &p)
{
if(this->name == p.name && this->age == p.age)
{
return true;
}
else
return false;
}
};
void test()
{
Person p1("tom", 18);
Person p2("tomw", 18);
if(p1 == p2)
{
cout << "p1 和 p2是相等的" << endl;
}
else
cout << "p1 和 p2是不相等的" << endl;
}
int main(void)
{
test();
}
6.函数调用的重载,没有固定的写法,根据作用自己设计
#include <iostream>
#include <string.h>
using namespace std;
class Print
{
public:
void operator()(string name) //重载的是()
{
cout << name << endl;
}
};
class Add
{
public:
int operator()(int num1, int num2)
{
int ret;
ret = num1 + num2;
return ret;
}
};
void Print2(string name)
{
cout << name << endl;
}
void test()
{
Print print;
print("hello world"); //因为调用形式像函数,因此称之为仿函数
Print2("hello world"); //这里是真正的函数调用
Add add;
int ret = add(10,10);
cout << "ret = " << ret << endl;
cout << "ret = " << Add()(10,10) << endl; //采用匿名的函数对象,当前行执行结束之后
//就会被释放,形式为 类名+()
}
int main(void)
{
test();
}