文章目录
- 运算符重载
- 1.1 运算符概述
- 1.2 运算符 + 重载
- 1.3 运算符 << 重载
运算符重载
1.1 运算符概述
针对当前程序中常用的运算符,可以实现目标运算符处理当前数据类型的方式修改
需求:
"ABCD" + "BDC" ==> "ABCDBDC" + ==> 拼接函数
1.2 运算符 + 重载
#include <iostream>#include <cstdio>
#include <cstdlib>
#include <cstring>using namespace std;class MyString
{
public:MyString() {}MyString(char *str){// strlen(str) 构造函数参数字符串长度size_t length = strlen(str);this->str = (char *)malloc(length + 1);memset(this->str, 0, length + 1);memcpy(this->str, str, length + 1);}MyString(const MyString &ms){size_t length = strlen(ms.str);str = (char *)malloc(length + 1);memset(str, 0, length + 1);memcpy(str, ms.str, length + 1);}~MyString(){free(str);str = NULL;}MyString *append(MyString *ms){/*1. 计算当前字符串总长度strlen(str) 调用函数的字符串长度strlen(ms->str) 参数字符串长度相加之后当前字符串总长度*/size_t length = strlen(str) + strlen(ms->str);// 2. 根据总长度申请的新的内存空间char *temp = (char *)malloc(length + 1);memset(temp, 0, length + 1);// 3. 将当前调用函数对象的 MyString 底层字符串数据拷贝到 temp 中memmove(temp, str, strlen(str));// 4. 将参数 MyString 对象底层字符串拼接到 temp 中strcat(temp, ms->str);// 5. 首先释放当前调用函数原本 str 内存空间free(str);// 6. 新申请的内存空间地址赋值给 strstr = temp;return this;}/*opreator++ 运算符重载格式要求1. 必须有友元函数,类外开可以直接调用并且可以操作当前类内权限限制数据2. opreator+ 重载要求必须有两个参数,且必须使用引用类型*/friend void operator+(MyString &m1, MyString &m2);char *getStr() { return str; }private:char *str;
};void operator+(MyString &m1, MyString &m2)
{/*ms1 对应 + 之前的内容ms2 对应 + 之后的内容*/cout << "m1 : " << m1.str << endl;cout << "m2 : " << m2.str << endl;cout << "+ 运算符重载" << endl;// 1. 计算总长度size_t length = strlen(m1.str) + strlen(m2.str);// 2. 申请新空间char *temp = (char *)calloc(1, length + 1);// 3. m1 数据内容存储到新空间中memcpy(temp, m1.str, strlen(m1.str));// 4. m2 数据内容拼接到新空间中strcat(temp, m2.str);// 5. 释放 m1 原空间数据内容free(m1.str);// 6. m1 底层字符串存储新空间地址m1.str = temp;
}int main(int argc, char const *argv[])
{MyString *ms1 = new MyString("ABC");MyString *ms2 = new MyString("1234");ms1 = ms1->append(ms2);/*MyString * operator+(MyString * m) 当前重载 + 运算符的函数是一个成员函数,需要通过 MyString 类型调用,但是 + 运算符属于基础运算符编译器在使用时,不会认为是【类型调用】编译器可以做的事情:1. + 运算符按照基本逻辑实现2. 如果发现基本逻辑无法满足执行要求,会检测到运算符两端的数据类型查询当前数据类型中是否存在对应的运算符的重载实现*/MyString *ms3 = new MyString("!@$");*ms1 + *ms3;cout << ms1->getStr() << endl;delete ms2;delete ms1;return 0;
}
1.3 运算符 << 重载
#include <iostream>
#include <string>using namespace std;class Person
{
public:Person() {}Person(int id, string name, int age) : id(id), name(name), age(age) {}Person(const Person &p) : id(p.id), name(p.name), age(p.age) {}/*当前函数是重载了 << 运算符1. ostream & o 输出操作使用的 cout2. Person * p 目标展示的 Person 数据<< 运算符重载替换的内容是 cout << p3. 返回值是 ostream & 输出流引用,方便连贯操作*/friend ostream &operator<<(ostream &o, Person *p);private:int id;string name;int age;
};ostream &operator<<(ostream &o, Person *p)
{o << "ID : " << p->id << ", Name : " << p->name << ", Age : " << p->age;return o;
}class Student
{
};int main(int argc, char const *argv[])
{Person *p1 = new Person(1, "张三", 3);Person *p2 = new Person(2, "李四", 5);Student *s = new Student;/*当前使用的 << 运算符已经被 ostream 重载之后的运算符内容cout 就是 ostream 类型ostream Output Stream 输出流*/cout << p1 << endl<< p2 << " 字符串" << endl;/*执行结果:ID : 1, Name : 张三, Age : 3ID : 2, Name : 李四, Age : 5 字符串*/cout << s << endl; // 0x903ca0return 0;
}cout << p1 << endl<< p2 << " 字符串" << endl;/*执行结果:ID : 1, Name : 张三, Age : 3ID : 2, Name : 李四, Age : 5 字符串*/cout << s << endl; // 0x903ca0return 0;
}