第四课 类和对象-运算符重载
4.5 C++运算符重载
4.5.1 加号运算符重载
作用:实现两个自定义数据类型相加的运算
class Number
{
public:
// 通过成员函数重载 + 运算符
Number operator+(Number& number)
{
Number temp;
temp.m_A = this->m_A + number.m_A;
temp.m_B = this->m_B + number.m_B;
return temp;
}
int m_A;
int m_B;
};
//// 通过全局函数 重载加号运算符
//Number operator+(Number& n1, Number& n2)
//{
// Number temp;
// temp.m_A = n1.m_A + n2.m_A;
// temp.m_B = n1.m_B + n2.m_B;
//
// return temp;
//}
void test01()
{
Number n1;
n1.m_A = 10;
n1.m_B = 25;
Number n2;
n2.m_A = 10;
n2.m_B = 25;
Number n3 = n1 + n2;
cout << n3.m_A << " " << n3.m_B << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
4.5.2 左移运算符重载
作用:可以输出自定义数据类型
class Person
{
public:
// 利用成员函数重载左移运算符 p.operator<<(p) 简化 p << cout
// 通常不会利用成员函数重载左移运算符,因为无实现 cout 在左侧
/*void operator<<(ostream &cout)
{
cout << "姓名:" << this->m_Name << " 年龄:" << this->m_Age << endl;
}*/
string m_Name;
int m_Age;
};
ostream& operator<<(ostream& cout,Person &p)
{
cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;
return cout;
}
void test01()
{
Person p1;
p1.m_Name = "张三";
p1.m_Age = 18;
//p1 << cout;
// 链式编程
cout << p1 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
4.5.3 递增运算符重载
作用:通过重载递增运算符,实现自己的整形数据
class Person
{
public:
// 重载前置++运算符 返回引用为了对一个数据进行递增操作
Person& operator++()
{
m_Age++;
return *this;
}
// 重载后置++运算符 int代表占位参数,可用于区分前置和后置递增
Person operator++(int)
{
Person temp = *this; // 局部对象的引用,当前函数结束后会释放;故返回值
m_Age++;
return temp;
}
int m_Age;
};
ostream& operator<<(ostream& cout, Person p)
{
cout << "年龄:" << p.m_Age << endl;
return cout;
}
void test01()
{
Person p;
p.m_Age = 23;
cout << ++(++p);
cout << p++;
cout << p;
}
int main()
{
test01();
system("pause");
return 0;
}
注意:前置递增返回引用,后置递增返回值
4.5.4 赋值运算符重载
C++编译器至少给一个类添加四个函数:
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝构造函数,对属性进行值拷贝
4.赋值运算符operator=对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
class Person
{
public:
Person& operator=(Person& p)
{
// 编译器提供的是浅拷贝
// m_Name = p.m_Name
// 应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
if (m_Name != NULL)
{
delete m_Name;
m_Name = NULL;
}
// 深拷贝
m_Name = new string(*p.m_Name);
// 返回对象本身
return *this;
}
Person(string name)
{
m_Name = new string(name);
}
~Person()
{
if (m_Name != NULL)
{
delete m_Name;
m_Name = NULL;
}
}
string *m_Name;
};
void test01()
{
Person p1("张三");
Person p2("李四");
Person p3("王五");
p1 = p2 = p3;
cout << *p1.m_Name << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
4.5.5 关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
class Person
{
public:
Person(string name, int age)
{
m_Name = name;
m_Age = age;
}
bool operator==(Person &p)
{
if (m_Name == p.m_Name && m_Age == p.m_Age)
{
return true;
}
return false;
}
bool operator!=(Person& p)
{
if (m_Name != p.m_Name || m_Age != p.m_Age)
{
return true;
}
return false;
}
string m_Name;
int m_Age;
};
void test01()
{
Person p1("dz", 25);
Person p2("dz", 25);
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()
{
test01();
system("pause");
return 0;
}
4.5.6 函数调用运算符重载
- 函数调用运算符()也可以重载
- 由于重载后使用的方法非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活
class MyPrint
{
public:
void operator()(string text)
{
cout << text << endl;
}
};
void MyPrint01(string text)
{
cout << text << endl;
}
void test01()
{
MyPrint myPrint;
myPrint("Hellow World"); // 由于使用起来非常类似于函数调用,因此称为仿函数
MyPrint01("Hellow World!");
}
// 仿函数非常灵活,没有固定的写法
// 加法类
class MyAdd
{
public:
int operator()(int num1,int num2)
{
return num1 + num2;
}
};
void test02()
{
MyAdd myAdd;
int sum = myAdd(25, 25);
cout << "sum = " << sum << endl;
// 匿名函数对象
cout << MyAdd()(125, 125) << endl;
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}

浙公网安备 33010602011771号