运算符重载概念:对己有的运算符重新进行定义,赋予其另一种功能 ,以适应不同的数据类型
一、加号运算符重载
作用:实现两个自定义数据类型相加的运算
示例:operator+(成员函数重载的使用方式)
#include <iostream>
using namespace std;
class Add
{
public:
Add()
{
m_A = 100;
m_B = 100;
}
Add operator+(Add a) //加号重载
{
Add temp;
temp.m_A = this->m_A + a.m_A;
temp.m_B = this->m_B + a.m_B;
return temp;
}
int m_A;
int m_B;
};
int main()
{
Add a,b,c;
a.m_A = 10;
a.m_B = 10;
b.m_A = 10;
b.m_B = 10;
c = a + b; //他的本质调用其实是Add c=a.operator+(b);
cout << c.m_A << endl;
cout<< c.m_B<<endl;
system("pause");
}
示例:operator+(全局函数重载的使用方式)
#include <iostream>
using namespace std;
class Add
{
public:
Add()
{
m_A = 100;
m_B = 100;
}
int m_A;
int m_B;
};
Add operator+(Add &a,Add &b) //加号重载
{
Add temp;
temp.m_A = a.m_A + b.m_A;
temp.m_B = b.m_B + b.m_B;
return temp;
}
int main()
{
Add a,b,c;
a.m_A = 10;
a.m_B = 10;
b.m_A = 10;
b.m_B = 10;
c = a + b; //他的本质调用其实是Add c=operator+(a,b);
cout << c.m_A << endl;
cout<< c.m_B<<endl;
system("pause");
}
二、左移运算符重载
作用:可以输出自定义数据类型
示例:operator<<(全局函数重载的使用方式)
注:成员函数重载左移运算符没有意义
#include <iostream>
using namespace std;
class Add
{
public:
int m_A;
int m_B;
};
ostream& operator<<(ostream &t,Add &b) //左移运算符重载,这里的&t是引用cout,是cout的别名,因此这里没有问题
{
t << "m_A=" << b.m_A << " m_B=" << b.m_B;
return t;
}
int main()
{
Add a;
a.m_A = 10;
a.m_B = 10;
cout << a<<endl<<a;
system("pause");
}
如果成员变量为私有,可以用友元声明来实现:
#include <iostream>
using namespace std;
class Add
{
friend ostream& operator<<(ostream& cout, Add& b); //友元声明
friend void test(); //友元声明
private:
int m_A; //私有的成员变量
int m_B; //私有的成员变量
};
ostream& operator<<(ostream &cout,Add &b) //左移运算符重载
{
cout << "m_A=" << b.m_A << " m_B=" << b.m_B;
return cout;
}
void test()
{
Add a;
a.m_A = 10;
a.m_B = 10;
cout << a << endl << a;
}
int main()
{
test();
system("pause");
}
三、递增运算符重载
作用:通过重载递增运算符,实现自己的整型数据
示例:前置和后置递增
#include <iostream>
using namespace std;
class Myint
{
friend ostream& operator<<(ostream& t, Myint m);
public:
Myint()
{
m_Num = 0;
}
Myint& operator++() //前置++运算符
{
m_Num++;
return *this;
}
Myint operator++(int) //后置++运算符
{
Myint temp=*this; //先记录当前的值
m_Num++; //再进行递增
return temp; //然后返回先前的值
}
private:
int m_Num;
};
ostream& operator<<(ostream& t, Myint m)
{
t << m.m_Num;
return t;
}
int main()
{
Myint myint;
cout<<"前置递增为:"<<endl;
cout << ++myint << endl;
cout << ++myint << endl;
cout<<"后置递增为:"<<endl;
cout << myint++ << endl;
cout << myint++ << endl;
system("pause");
}
四、赋值运算符重载
C++编译器至少给一个类添加4个函数
- 默认构造函数,函数体为空
- 默认析构函数,函数体为空
- 默认拷贝构造函数(无参,函数体为空)
- 默认运算符operator=,对属性进行值拷贝
示例:operator=
#include <iostream>
using namespace std;
class Person
{
public:
Person(int age)
{
m_Age = new int(age);
}
Person& operator=(const Person &p) //重载赋值运算符
{
//m_Age = p.m_Age 这个是编译器提供的浅拷贝
if (m_Age != NULL) //应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
{
delete m_Age;
m_Age = NULL;
}
this->m_Age = new int(*p.m_Age); //然后做深拷贝的操作
return *this;
}
~Person()
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
int* m_Age;
};
void test()
{
Person p1(10);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
cout << *p1.m_Age << endl;
cout << *p2.m_Age << endl;
cout << *p3.m_Age << endl;
}
int main()
{
test();
}
五、关系运算符重载
示例:operator==和operator!=
#include <iostream>
using namespace std;
class Person
{
public:
Person(string name,int age)
{
m_Age = age;
m_Name = name;
}
int m_Age;
string m_Name;
bool operator==(Person& p) //重载关系运算符operator==
{
if (this->m_Age == p.m_Age && this->m_Name == p.m_Name)
{
return true;
}
else
{
return false;
}
}
bool operator!=(Person& p)
{
if (this->m_Age != p.m_Age || this->m_Name != p.m_Name)
{
return true;
}
else
{
return false;
}
}
};
void test()
{
Person p1("tom", 18);
Person p2("tom", 28);
if (p1 == p2)
{
cout << "p1和p2是相等的"<<endl;
}
else
{
cout << "p1和p2是不相等的" << endl;
}
if (p1 != p2)
{
cout << "p1和p2是不相等的" << endl;
}
else
{
cout << "p1和p2是相等的" << endl;
}
}
int main()
{
test();
}
六、函数调用运算符重载
- 函数调用运算符()也可以重载
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活
示例:operator()
结果:#include <iostream> using namespace std; class MyPrint { public: void operator()(string text) //函数调用运算符重载 因为调用时非常像函数,所以也叫仿函数 { cout << text; } }; void test() { MyPrint print; print("hello word!\n"); //调用重载 } int main() { test(); }
**