1 加号运算符重载:
1.1//成员函数实现 + 号运算符重载
实现语句:
Person operator+( Person& p)//传入一个新的参数于之前的相加。
{//不存在调用关系。暗含关系。
Person temp;
temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B;
return temp;
}
本质调用语句:
Person p3 = p2.operator + (p1);//成员函数本质调用。
cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;
1.2运算符重载 可以发生函数重载
实现语句:
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 p4 = operator+(p1, p2);
cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;
起始他们有通用调用语句。
Person p4 = p2 + p1;
外传“:另外实现语句:(类与int 类型的调用模式)
运算符重载 可以发生函数重载
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;
}
本质调用语句:
Person p4 = operator+(p2, 10);
总代码
```C++
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 = p2 + p1; //相当于 p2.operaor+(p1)
cout << "mA:" << p3.m_A << " mB:" << p3.m_B << endl;
Person p4 = p3 + 10; //相当于 operator+(p3,10)
cout << "mA:" << p4.m_A << " mB:" << p4.m_B << endl;
}
int main() {
test();
system("pause");
return 0;
}
```
> 总结1:对于内置的数据类型的表达式的的运算符是不可能改变的
> 总结2:不要滥用运算符重载
可能出现错误:
只能同时拥有一个相关运算符。
2 左移运算符重载
作用:可以输出自定义数据类型
#include <iostream>
#include <string>
using namespace std;
class Person
{
friend ostream& operator<<(ostream& cout, Person& p);
public:
Person(int a,int c)
{
m_a = a;
m_b = c;
}
private:
int m_a;
int m_b;
};
ostream& operator<<(ostream& cout, Person& p)
{
cout << "p.m_a" << p.m_a << endl;
cout << "p.m_b" << p.m_b << endl;
return cout;
}
void test01()
{
Person p(10000000,222222);
cout << p;
}
int main()
{ //Person p;
test01();
return 0;
}
声明://全局函数实现左移重载
//ostream对象只能有一个
ostream& operator<<(ostream& out, Person& p) {//由于是(引用)起别名所以不用cout也可以
out << "a:" << p.m_A << " b:" << p.m_B;//ostream表示输出流,英文”output stream“的简称。在 C++中常见的输出流对象就是标准输出流cout,
3 递增运算符重载
总代码:
#include <iostream>
#include <string>
using namespace std;
class MyInteger {
friend ostream& operator<<(ostream& out, MyInteger myint);
public:
MyInteger() {
m_Num = 0;
}
//前置++
MyInteger& operator++() {//如果不返回MyInte&类型那么不是对同一个数据类型++;所以不能改成MyInteger返回类型;
//先++
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;
}
后置--
}//后置--;
MyInteger operator--(int) {//占位运算符,区分前置与后置。
//先返回
MyInteger temp = *this;
m_Num--;
return temp;
}
void test03()//后置-- 先返回 再--
{
MyInteger myInt;
cout << myInt-- << endl;
cout << myInt << endl;
}
前置--
MyInteger& operator--()
{
m_Num--;
//再返回
return *this;
}
void test04()//前置-- 再--先返回/
{
MyInteger myInt;
cout << --myInt << endl;
cout << myInt << endl;
}
> 总结: 前置递增返回引用,后置递增返回值
.4 赋值运算符重载
c++编译器至少给一个类添加4个函数
1. 默认构造函数(无参,函数体为空)
2. 默认析构函数(无参,函数体为空)
3. 默认拷贝构造函数,对属性进行值拷贝
4. 赋值运算符 operator=, 对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
#include <iostream>
#include <string>
using namespace std;
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 关系运算符重载
**作用:**重载关系运算符,可以让两个自定义类型对象进行对比操作
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
};
bool operator==(Person & p)
{
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
{
return true;
}
else
{
return false;
}
}
bool operator!=(Person & p)
{
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
{
return false;
}
else
{
return true;
}
}
string m_Name;
int m_Age;
};
void test01()
{
//int a = 0;
//int b = 0;
Person a("孙悟空", 18);
Person b("孙悟空", 18);
if (a == b)
{
cout << "a和b相等" << endl;
}
else
{
cout << "a和b不相等" << endl;
}
if (a != b)
{
cout << "a和b不相等" << endl;
}
else
{
cout << "a和b相等" << endl;
}
}
int main() {
test01();
system("pause");
return 0;
}
.6 函数调用运算符重载
* 函数调用运算符 () 也可以重载
* 由于重载后使用的方式非常像函数的调用,因此称为仿函数
* 仿函数没有固定写法,非常灵活
```C++
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;
}