运算符重载是使用户可以对已有的运算符进行重载,从而实现对自定义的数据类型的运算操作
- 1、运算重载符不可以改变语法结构。
- 2、运算重载符不可以改变操作数的个数。
- 3、运算重载符不可以改变优先级。
- 4、运算重载符不可以改变结合性。
1.加号运算符重载
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student(int age)
{
this->age = age; //等价于Student::age = age;
//this指针指向被调用的成员函数所属的对象
};
int age;
//成员函数作运算符重载
Student &operator+(Student &s1)
{
this->age += s1.age;
return *this;
};
private:
string arr = "你是大傻逼";
};
//全局函数作运算符重载
Student operator+(Student &s1, Student &s2)
{
Student temp(0);
temp.age = s1.age + s2.age;
return temp;
};
int main()
{
Student s1(10);
Student s2(10);
Student s3 = s1 + s2;
cout << s3.age << endl;
system("pause");
return 0;
}
2.左移运算符
与cout结合运用,实现输出自定义数据类型.
#include <iostream>
#include <string>
using namespace std;
class Student
{
friend ostream &operator<<(Student &s1,ostream &cout);
friend ostream &operator<<(ostream &cout,Student &s1);
public:
Student(int age)
{
this->age = age; //等价于Student::age = age;
//this指针指向被调用的成员函数所属的对象
};
int age;
//成员函数作运算符重载
/* Student &operator+(Student &s1)
{
this->age += s1.age;
return *this;
};
*/
private:
string arr = "你是大傻逼";
};
//全局函数作运算符重载
Student operator+(Student &s1, Student &s2)
{
Student temp(0);
temp.age = s1.age + s2.age;
return temp;
};
ostream &operator<<( Student &s1,ostream &cout)
{
cout << "student age = " << s1.age <<"student arr = "<<s1.arr<< endl;
return cout;
}
ostream &operator<<(ostream &cout,Student &s1)
{
cout << "student age = " << s1.age <<"student arr = "<<s1.arr<< endl;
return cout;
}
int main()
{
Student s1(10);
Student s2(10);
Student s3 = s1 + s2;
s3 << cout << endl;//ostream &operator<<( Student &s1,ostream &cout)
cout<<s3;//ostream &operator<<(ostream &cout,Student &s1)
system("pause");
return 0;
}
注意以下代码实现的区别
ostream &operator<<(Student &s1,ostream &cout);
ostream &operator<<(ostream &cout,Student &s1);
3.++运算符重载
注意前置递增和后置递增返回值类型的区别
前置递增返回对象本身
后置递增函数内直接对对象值进行操作,然后返回未操作前的对象的值。
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; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;
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() {
test01();
//test02();
system("pause");
return 0;
}
4.赋值运算符重载
c++编译器至少给一个类添加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 p1(18);
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() {
test01();
//int a = 10;
//int b = 20;
//int c = 30;
//c = b = a;
//cout << "a = " << a << endl;
//cout << "b = " << b << endl;
//cout << "c = " << c << endl;
system("pause");
return 0;
}
5.关系运算符重载
#include <iostream>
#include <string>
using namespace std;
class Student
{
friend ostream &operator<<(Student &s1, ostream &cout);
friend ostream &operator<<(ostream &cout, Student &s1);
public:
Student(int age)
{
this->age = age; //等价于Student::age = age;
//this指针指向被调用的成员函数所属的对象
};
bool operator==(Student &s1)
{
if (this->age == s1.age && this->arr == s1.arr)
return true;
else
return false;
};
int age;
//成员函数作运算符重载
/* Student &operator+(Student &s1)
{
this->age += s1.age;
return *this;
};
*/
private:
string arr = "你是大傻逼";
};
//全局函数作运算符重载
Student operator+(Student &s1, Student &s2)
{
Student temp(0);
temp.age = s1.age + s2.age;
return temp;
};
ostream &operator<<(Student &s1, ostream &cout)
{
cout << "student age = " << s1.age << "student arr = " << s1.arr << endl;
return cout;
}
ostream &operator<<(ostream &cout, Student &s1)
{
cout << "student age = " << s1.age << "student arr = " << s1.arr << endl;
return cout;
}
int main()
{
Student s1(10);
Student s2(10);
Student s3 = s1 + s2;
if (s1 == s2)
{
cout << "这俩相等" << endl; /* code */
}
s3 << cout << endl; //ostream &operator<<( Student &s1,ostream &cout)
cout << s3; //ostream &operator<<(ostream &cout,Student &s1)
system("pause");
return 0;
}
6.()运算符重载&仿函数
- 函数调用运算符 () 也可以重载
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活
-
class MyPrint { public: void operator()(string text) { cout << text << endl; } }; void test01() { //重载的()操作符 也称为仿函数 MyPrint myFunc; myFunc("hello world"); } 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) = " << MyAdd()(100, 100) << endl; } int main() { test01(); test02(); system("pause"); return 0; }
MyAdd():匿名对象,Myadd类型的一个对象,在代码执行后内存立即释放.