• c++中的重载


    知识点1【运算符重载】

    1、重载运算符的概述

    运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
    运算符重载的目的:简化操作,让已有的运算符,适应不同的数据类型。
    语法:函数的名字有关键字operator及其紧跟的运算符组成。
    比如:重载+运算符 ==> operator+
    注意:重载运算符不要更改运算符的本质操作(+是数据的相加,不要重载成相减)

    2、运算符<<的重载

    #include 
    #include
    
    using namespace std;
    
    class Person{
        friend ostream& operator<<(ostream &out,Person &person);
    private:
        int age;
        char* name;
    public:
        Person(int age, char* name){
            this->age = age;
            this->name = new char[strlen(name)+1];
            strcpy(this->name,name);
            cout << "构造函数" << endl;
        }
    
        void printPerson(){
            cout << "name = " << this->name << ", age = " << this->age << endl;
        }
        ~Person(){
            if(this->name != NULL){
                delete [] this->name;
                this->name = NULL;
            }
            cout << "析构函数" << endl;
        }
    };
    
    ostream& operator<<(ostream &out,Person &person){
        out << "name = " << person.name << ", age = " << person.age << endl;
        return out;
    }
    
    int main(int argc, char *argv[])
    {
        Person person = Person(18,"lucy");
    
        //普通的成员函数,遍历信息
        person.printPerson();
        //cout默认输出方式无法识别自定义对象输出格式
        //对<<运算符重载
        //运算符重载调用方法1
        operator<<(cout,person);
        //运算符重载的调用方式2,
        //对方法1 进行优化 去掉operator,第一个参数 放在运算符<<的左边 第二个参数 放在运算符<<的右边
        cout << person << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    运算结果:
    在这里插入图片描述

    3、重载+运算符

    注意:1+1这种情况下,不需要重载,编译器能够计算

    #include 
    #include
    
    using namespace std;
    
    class Person{
        friend ostream& operator<<(ostream &out,Person &person);
        friend Person operator+(Person &ob1,Person &ob2);
    private:
        int age;
        char* name;
    public:
        Person(){
             cout << "新构造函数" << endl;
        }
        Person(int age, char* name){
            this->age = age;
            this->name = new char[strlen(name)+1];
            strcpy(this->name,name);
            cout << "构造函数" << endl;
        }
    
        void printPerson(){
            cout << "name = " << this->name << ", age = " << this->age << endl;
        }
        ~Person(){
            if(this->name != NULL){
                delete [] this->name;
                this->name = NULL;
            }
            cout << "析构函数" << endl;
        }
    };
    
    ostream& operator<<(ostream &out,Person &person){
        out << "name = " << person.name << ", age = " << person.age << endl;
        return out;
    }
    
    Person operator+(Person &ob1,Person &ob2){
        Person person;
        person.age = ob1.age + ob2.age;
        person.name = new char[strlen(ob1.name) + strlen(ob2.name) +1];
        strcpy(person.name,ob1.name);
        strcat(person.name,ob2.name);
    
        return person;
    }
    
    int main(int argc, char *argv[])
    {
        Person person = Person(18,"lucy");
    
        //普通的成员函数,遍历信息
        person.printPerson();
        //cout默认输出方式无法识别自定义对象输出格式
        //对<<运算符重载
        //运算符重载调用方法1
        operator<<(cout,person);
        //运算符重载的调用方式2,
        //对方法1 进行优化 去掉operator,第一个参数 放在运算符<<的左边 第二个参数 放在运算符<<的右边
        cout << person << endl;
    
        Person person1 = Person(18,"lucy");
        Person person2 = Person(18,"lucy");
        Person ob = person1+person2;
        cout << ob << endl;
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    知识点4【可重载的运算符】(了解)

    在这里插入图片描述

    知识点5【重载自增或自减 ++ --运算符】

    operator++
    编译器看到++a(前置++),他就调用operator++(a),当编译器看到a++(后置++),他就会去调用operator++(a,int).

    #include 
    
    using namespace std;
    
    class Data{
        friend ostream& operator<<(ostream& out,Data& ob);
    private:
        int a;
        int b;
    public:
        Data(){
            cout << "无参构造函数" << endl;
        }
    
        Data(int a, int b):a(a),b(b){
            cout << "有参构造" << endl;
        }
    
        void showData(){
            cout << "a = "<< a <<", b= "<< b << endl;
        }
    
        //成员函数 重载前置++ ++ob1 (先加 后使用)
        //编译器 默认识别 operator++(a) //但是a可以用this代替 从而化简 operator++()
        Data& operator++(){
            a++;
            b++;
            return *this;
        }
    
        //成员函数 重载后置++ ++ob1 (先使用 后加)
        Data& operator++(int){
            static Data ob1 = *this;
    
            a++;
            b++;
            return ob1;
        }
    
        ~Data(){
            cout << "析构函数" << endl;
        }
    
    };
    
    ostream& operator<<(ostream& out,Data& ob){
        out << "a = "<< ob.a <<", b= "<< ob.b << endl;
        return out;
    }
    
    int main(int argc, char *argv[])
    {
        Data data = Data(10,20);
        cout << data;
    
        //成员函数,重载++运算符
        //Data ob1;
        cout << ++data <<endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    知识点5【重载=运算符】

    前提1:类中没有指针成员,不需要重载=运算符(默认的浅拷贝就可以完成),类中有指针成员,必须重载=运算符。

    class Person{
    private:
        char *name;
    public:
        Person(){
            name = NULL;
            cout << "无参构造" << endl;
        }
    
        Person(char *name){
            this->name = new char[strlen(name)+1];
            strcpy(this->name,name);
            cout << "有参构造" <<endl;
        }
    
        Person(const Person& ob){
            //this代表的是新对象
            cout<<"拷贝构造函数"<<endl;
            this->name = new char[strlen(ob.name)+1];
            strcpy(this->name, ob.name);
        }
    
        ~Person(){
            cout<<"析构函数"<<endl;
            if(this->name != NULL){
                delete [] this->name;
                this->name = NULL;
            }
        }
    
        void showPerson(){
            cout<<"name = "<<name<<endl;
        }
    
        //成员函数 重载=运算符
        Person& operator=(Person &ob){
            if(this->name != NULL){
                delete [] this->name;
                this->name = NULL;
            }
            this->name = new char[strlen(ob.name) +1];
            strcpy(this->name,ob.name);
            return *this;
        }
    };
    
    void test01(){
        Person ob1("lucy");
        ob1.showPerson();
    
        Person ob2 = ob1;//调用拷贝构造
    
        Person ob3("bob");
        //不重载 = 默认是浅拷贝
        ob3 = ob1;
    
        ob3.showPerson();
    
        Person ob6,ob5,ob4;
        ob6 = ob5 = ob4 = ob1;
        ob6.showPerson();
    
    }
    
    int main(int argc, char *argv[])
    {
        test01();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    知识点6【等于和不等于(==、!=)运算符重载】

    //重载==运算符
        bool operator==(Person &ob){
            if(strcmp(this->name,ob.name) == 0){
                return true;
            }
            return false;
        }
    
        //重载!=运算符
        bool operator!=(Person &ob){
            if(strcmp(this->name,ob.name )!= 0){
                return true;
            }
            return false;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    知识点7【不要重载&&、||】

    不要重载&&、|| 因为 用户无法实现 && ||的短路特性。
    && 短路特性: A && B 如果A为假 B将不会执行
    || 短路特性: A || B 如果A为真 B将不会执行

    知识点8【符号重载的总结】

    在这里插入图片描述

    知识点9【强化训练字符串类String】

    String包括字符串以及字符串的操作:
    mystring.h:

    #ifndef MYSTRING_H
    #define MYSTRING_H
    #include 
    using namespace std;
    
    
    class MyString
    {
        friend ostream& operator<<(ostream &out,MyString &ob);
        friend istream &operator>>(istream &in, MyString &ob);
    private:
        char *str;
        int size;
    public:
        MyString();
        MyString(const char *str);
        MyString(const MyString &ob);
        ~MyString();
        int Size();
    
        //重载[]
        char& operator[](int index);
        //重载=
        MyString& operator=( MyString& ob1);
        MyString& operator=(char* str);
        //重载+
        MyString& operator+(const MyString &ob);
        MyString& operator+(const char* str);
        //重载==
        bool operator ==(const MyString &ob);
        bool operator ==(const char* str);
    };
    
    ostream& operator<<(ostream &out,MyString &ob);
    istream& operator>>(istream &in, MyString &ob);
    
    
    #endif // MYSTRING_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    mystring.cpp

    #include "mystring.h"
    #include
    #include 
    
    MyString::MyString()
    {
        this->str = NULL;
        this->size = 0;
        cout<<"无参构造"<<endl;
    }
    
    MyString::MyString(const char *str)
    {
        cout<<"char *构造函数"<<endl;
        this->str = new char[strlen(str)+1];
        strcpy(this->str,str);
        this->size = strlen(str);
    }
    
    MyString::MyString(const MyString &ob)
    {
         cout<<"拷贝构造函数"<<endl;
         this->str = new char[strlen(ob.str)+1];
         strcpy(ob.str,str);
         this->size = ob.size;
    
    }
    
    MyString::~MyString()
    {
        cout<<"析构函数"<<endl;
        if(this->str != NULL)
        {
            delete [] this->str;
            this->str = NULL;
        }
    }
    
    int MyString::Size()
    {
        return this->size;
    }
    
    char& MyString::operator[](int index)
    {
        if(index < this->size && index >=0){
            return this->str[index];
        }else{
            cout<<"index无效"<<endl;
        }
    }
    
    MyString &MyString::operator=(MyString &ob1)
    {
        if(this->str != NULL){
            delete [] this->str;
            this->str = NULL;
        }
        this->str = new char[strlen(ob1.str)+1];
        strcpy(this->str,ob1.str);
        this->size = ob1.size;
        return *this;
    }
    
    MyString &MyString::operator=(char *str)
    {
        if(this->str != NULL){
            delete [] this->str;
            this->str = NULL;
        }
        this->str = new char[strlen(str)+1];
        strcpy(this->str,str);
        this->size = strlen(str);
        return *this;
    }
    
    MyString &MyString::operator+(const MyString &ob)
    {
        static MyString ob1;
        ob1.str = new char[this->size + ob.size + 1];
        strcpy(ob1.str,this->str);
        strcat(ob1.str,ob.str);
        ob1.size = this->size + ob.size;
        return ob1;
    }
    
    MyString &MyString::operator+(const char *str)
    {
        static MyString ob1;
        ob1.str = new char[this->size + strlen(str) + 1];
        strcpy(ob1.str,this->str);
        strcat(ob1.str,str);
        ob1.size = this->size + strlen(str);
        return ob1;
    }
    
    bool MyString::operator ==(const MyString &ob)
    {
        if((strcmp(this->str, ob.str) == 0) && (this->size == ob.size)){
            return true;
        }
        return false;
    }
    
    bool MyString::operator ==(const char *str)
    {
        if((strcmp(this->str, str) == 0) && (this->size == strlen(str))){
            return true;
        }
        return false;
    }
    
    ostream& operator<<(ostream &out,MyString &ob){
        out << ob.str << endl;
        return out;
    }
    
    
    istream &operator>>(istream &in, MyString &ob)
    {
        //记得将原有的数据进行清除
        if(ob.str != NULL){
            delete [] ob.str;
        }
        //获取键盘输入的字符串
        char buf[1024];
        in >> buf;//先得到键盘输入的数据,然后根据buff的大小,开辟空间
    
        ob.str = new char[strlen(buf)+1];
        strcpy(ob.str,buf);
        ob.size = strlen(buf);
        return in;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134

    main.cpp:

    #include 
    #include "mystring.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        MyString str1 =  MyString("lucy");
    
        //自定义对象 必须重载<<(普通全局友元函数实现)
        cout << str1 << endl;
        cout << "size = " << str1.Size() <<endl;
    
        //自定义对象 必须重载>>(普通全局友元函数实现)
        cin >> str1;
        cout << str1 << endl;
        cout << "size = " << str1.Size() <<endl;
    
        //重载[]运算符
        MyString str2("hello class");
        cout<<str2[1]<<endl;
    
        //重载[]运算符,返回值必须是左值,才能写操作
        //重载[]运算符的返回值必须是引用
        str2[1] ='E';
        cout<<str2<<endl;
    
        //将对象str2 赋值 给str3
        //(默认赋值语句 浅拷贝)
        //必须重载=运算符(成员函数完成)
        MyString str3("hello str3");
        cout<<"str3:"<<str3<<endl;
    
        str3 = str2;
        cout<<"str3:"<<str3<<endl;
    
        MyString str4("hello str4");
        cout<<"str4:"<<str4<<", size = "<<str4.Size()<<endl;
        //必须重载=运算符(成员函数完成)
        str4="hello string";
        cout<<"str4:"<<str4<<", size = "<<str4.Size()<<endl;
    
        //重载+运算符
        MyString str5("我爱大家");
        MyString str6("我爱千锋");
        cout<<str5+str6<<endl;
    
        MyString str7("大家爱我");
        cout<< str7+"千锋爱我"<<endl;
    
        //重载==运算符
        //重载==运算符
        MyString str8("hehe");
        MyString str9("haha");
        if(str8 == str9)
        {
            cout<<"相等"<<endl;
        }
        else
        {
            cout<<"不相等"<<endl;
        }
    
        if(str8 == "hehe")
        {
            cout<<"相等"<<endl;
        }
        else
        {
            cout<<"不相等"<<endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
  • 相关阅读:
    1.6-02:陶陶摘苹果
    算法通关村之字符串(实战训练)经典问题:转换小写字母、字符串反转、K个一组反转、仅反转字母
    Coordinatorlayout:协调员布局
    基于Spring Boot和Kubernetes的RESTful微服务
    使用 prometheus 监控 MySQL
    进程之理解进程的概念
    webpack中的代理配置
    GO语言-反射reflect
    类方法,静态方法和实例方法的区别及应用场景
    Critical Point ( local minima && saddle point)
  • 原文地址:https://blog.csdn.net/DUANJIAWEIDUANJIAWEI/article/details/126558141