• C++运算符重载


    +运算符重载

    #include 
    using namespace std;
    
    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
    };
    
    Number operator+(const Number &n1, const Number &n2) {
        Number result(0);
        result.value = n1.value + n2.value;
        return result;
    }
    
    Number operator+(const Number &n1, int n2) {
        Number result(0);
        result.value = n1.value + n2;
        return result;
    }
    
    int main() {
        Number num1 = Number(10) + Number(20);
        Number num2 = Number(10) + 5;
        cout << "num1 = " << num1.value << endl;
        cout << "num2 = " << num2.value << 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

    函数中的参数顺序和调用顺序必须一致,如下面的调用就报错了:

    在这里插入图片描述
    我们定义Numberint相加的函数时,Number参数是在前面的,则在使用时也必须保持Number在前面。

    定义的顺序也可以修改,必须让int在前面,则调用的时候int就要写在前面如下:
    在这里插入图片描述

    <<运算符重载

    与加号运算符一样,可以声明为类的成员函数,也可以声明为全局函数,这里就只写一种,示例如下:

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
    };
    
    Number& operator<<(Number & n1, Number & n2) {
        n1.value = n1.value + n2.value;
        return n1;
    }
    
    int main() {
        Number n1 = Number(1);
        Number n2 = Number(2);
        Number n3 = Number(3);
        Number result = n1 << n2 << n3;
        cout << result.value << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注:左移运算符的返回值必须是引用类型才能连续调用左移符号,否则只能调用一次,如下:

    Number operator<<(Number & n1, Number & n2) {
        n1.value = n1.value + n2.value;
        return n1;
    }
    
    int main() {
        Number n1 = Number(1);
        Number n2 = Number(2);
        Number result = n1 << n2;
        cout << result.value << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如上代码,<<函数的返回值不是引用类型的,则<<不能连续使用,如下是错误的:

    在这里插入图片描述
    另外需要注意,对象不能使用匿名对象,匿名对象无法使用<<来操作,如下是错误的:
    在这里插入图片描述
    另外,<<函数也是可以重载的,如下:

    Number & operator<<(Number & n1, Number & n2) {
        n1.value = n1.value + n2.value;
        return n1;
    }
    
    Number & operator<<(Number & n1, int n2) {
        n1.value = n1.value + n2;
        return n1;
    }
    
    int main() {
        Number n1 = Number(1);
        Number n2 = Number(2);
        Number n3 = Number(3);
        Number result = n1 << n2 << n3 << 4 << 5;
        cout << result.value << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    另外,如果访问了类的私有成员,也可以设置为友元,如下:

    class Number {
        friend Number & operator<<(Number & n1, Number & n2);
        friend Number & operator<<(Number & n1, int n2);
        friend int main();
    private:
        int value;
    public:
        explicit Number(int n) : value(n) { }
    
    };
    
    Number & operator<<(Number & n1, Number & n2) {
        n1.value = n1.value + n2.value;
        return n1;
    }
    
    Number & operator<<(Number & n1, int n2) {
        n1.value = n1.value + n2;
        return n1;
    }
    
    int main() {
        Number n1 = Number(1);
        Number n2 = Number(2);
        Number n3 = Number(3);
        Number result = n1 << n2 << n3 << 4 << 5;
        cout << result.value << 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

    通过<<实现打印对象,如下:
    在这里插入图片描述
    如上代码,cout不知道如何打印Number对象,所以IDE直接就报错了,说白了就是系统库并没有提供接收Number参数的<<函数,所以我们自己可以提供一个,如下:

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
    };
    
    ostream & operator<<(ostream & out, const Number & number) {
        printf("number.value = %d ", number.value);
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(3);
        cout << n1 << n2 << "hello" << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行结果如下:

    number.value = 1 number.value = 3 hello
    
    • 1

    ++运算符重载

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
    
        // 前++
        Number & operator++() {
            value++;
            return *this;
        }
    
        // 后++
        Number operator++(int) {
            Number copy = *this; // 利用拷贝构造函数创建出一个复本
            value++;
            return copy;
        }
    };
    
    ostream & operator<<(ostream & out, const Number & number) {
        out << number.value;
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(1);
        cout << ++n1 << endl;
        cout << n2++ << endl; // 这里打印的并不是n2,而是++操作返回的一个副本对象
        cout << n2 << 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

    赋值运算符重载

    c++编译器至少给一个类添加4个函数:

    • 默认构造函数(无参,函数体为空)
    • 默认析构函数(无参,函数体为空)
    • 默认拷贝构造函数,对属性进行值拷贝
    • 赋值运算符 operator=, 对属性进行值拷贝(会有浅拷贝的问题)

    示例如下:

    class Number;
    
    ostream & operator<<(ostream & out, const Number & number);
    
    class Number {
    public:
        int * valuePointer;
        explicit Number(int n) {
            valuePointer = new int(n);
        }
        ~Number() {
            delete valuePointer;
        }
    
        Number & operator=(const Number& number) {
            // 预防浅拷贝问题,编译器默认是浅拷贝,如:valuePointer = number.valuePointer
            cout << "自身value = " << *valuePointer << ", 传入value = " << *number.valuePointer << endl;
            *valuePointer = *number.valuePointer;
            return *this;
        }
    
    };
    
    ostream & operator<<(ostream & out, const Number & number) {
        out << *number.valuePointer;
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(2);
        Number n3(3);
        n1 = n2 = n3;
        cout << n1 << endl;
        cout << n2 << endl;
        cout << n3 << 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

    运行结果如下:

    自身value = 2, 传入value = 3
    自身value = 1, 传入value = 3
    3
    3
    3
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这说明赋值操作的优先级是从右到左的。

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
    };
    
    bool operator==(Number & n1, Number & n2) {
        return n1.value == n2.value;
    }
    
    ostream & operator<<(ostream & out, const Number & number) {
        out << number.value;
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(2);
        Number n3(2);
        bool result1 = n1 == n2;
        bool result2 = n2 == n3;
        cout << result1 << endl;
        cout << result2 << 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

    还有其它的关系,比如:<>!=>=<=等,这些的实现也是一样的,就不写了。

    函数调用运行符重载

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
        void operator()() {
            cout << "函数调用: " << value << endl;
        }
    };
    
    ostream & operator<<(ostream & out, const Number & number) {
        out << number.value;
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(2);
        Number n3(3);
        n1();
        n2();
        n3();
        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

    这个函数调用很奇怪,不知道为什么要搞这种形式。还可加入参数,示例如下:

    class Number {
    public:
        int value;
        explicit Number(int n) : value(n) { }
        void operator()() {
            cout << "函数调用: " << value << endl;
        }
        void operator()(int a, string b) {
            cout << "函数调用: " << value + a << b << endl;
        }
    };
    
    ostream & operator<<(ostream & out, const Number & number) {
        out << number.value;
        return out;
    }
    
    int main() {
        Number n1(1);
        Number n2(2);
        Number n3(3);
        n1(1, "一");
        n2(2, "二");
        n3(3, "三");
        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
  • 相关阅读:
    解决鸿蒙模拟器卡顿的问题
    Going Deeper With Convolution(GoogLeNet的理解)
    MySQL补充开窗函数
    腾讯云健康码+行程码OCR文字识别
    easyexcel读取文件
    Spring_01 快速入门 ioc的用途&注入&整合
    (入门自用)--C++--抽象类--多态原理--虚表--1020
    这几个与windows10有关的操作,可以帮助你更好地使用电脑
    项目练习:房屋出租系统
    Springboot整合taos时序数据库TDengine
  • 原文地址:https://blog.csdn.net/android_cai_niao/article/details/127576214