C++(24)运算符重载

概念

所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能,因此,一个函数名就可以用来代表不同功能的函数,也就是”一名多用”。

运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。例如,大 家都已习惯于用加法运算符”+”对整数、单精度数和双精度数进行加法运算,如5+8, 5.8 +3.67等,其实计算机对整数、单精度数和双精度数的加法操作过程是很不相同的, 但由于C++已经对运算符”+”进行了重载,所以就能适用于int, float, double类型的运算。

又如”<<“是C++的位运算中的位移运算符(左移),但在输出操作中又是与流对 象cout 配合使用的流插入运算符,”>>“也是位移运算符(右移),但在输入操作中又是与流对象 cin 配合使用的流提取运算符。这就是运算符重载(operator overloading)。C++系统对”<<“和”>>“进行了重载,用户在不同的场合下使用它们时,作用是不同 的。对”<<“和”>>“的重载处理是放在头文件stream中的。因此,如果要在程序中用”<< “和”>>”作流插入运算符和流提取运算符,必须在本文件模块中包含头文件stream(当然还应当包括”using namespace std“)。

运算符重载

1为什么会用运算符重载机制
用复数类举例
Complex c3 = c1 + c2;
原因 Complex是用户自定义类型,编译器根本不知道如何进行加减
编译器给提供了一种机制,让用户自己去完成,自定义类型的加减操作。。。。。
这个机制就是运算符重载机制
2 运算符重载的本质是一个函数

重载运算符的限制

不能重载的运算符
(1) . (2) : : (3) .* (4) ? : (5) sizeof

一些原则
(1)不改变运算符的优先级
(2)不改变运算符的结合性
(3)不改变运算符所需要的操作数
(4)不能创建新的运算符

#include <iostream>

using namespace std;

// 2 + 3i   实部 虚部
class Complex
{
    friend Complex add (const Complex &c1, const Complex &c2);
    friend Complex operator+(const Complex &c1, const Complex &c2);
    friend Complex operator+(const Complex &c1, int num);
public:
    Complex()
    {
        a = 0;
        b = 0;
    }

    Complex(int a, int b)
    {
        this->a = a;
        this->b = b;
    }

    void print()
    {
        printf ("%d + %di\n", a, b);
    }

    Complex add(const Complex &c2)
    {
        Complex tmp(a+c2.a, b+c2.b);
        return tmp;
    }

    Complex operator-(const Complex &c2) const
    {
        Complex tmp(a-c2.a, b-c2.b);
        return tmp;
    }
private:
    int a;  // 实部
    int b;  // 虚部
};

Complex add(const Complex &c1, const Complex &c2)
{
    Complex tmp(c1.a+c2.a, c1.b+c2.b);
    return tmp;
}

// 全局函数
// operator+ 可以理解成一个函数名
Complex operator+(const Complex &c1, const Complex &c2)
{
    Complex tmp(c1.a+c2.a, c1.b+c2.b);
    return tmp;
}

Complex operator+(const Complex &c1, int num)
{
    Complex tmp(c1.a + num, c1.b);
    return tmp;
}

// 运算符重载的内部函数写法
int main3_2()
{
    Complex c1(1,2), c2(3,4), c;
    // c = c1 + c2; 

    // 全局使用
    c = operator+(c1, c2);

    // 内部使用
    c = c1.add(c2);

    // 运算符重载 内部 和 全局函数 同时只能存在一个
    // 全局到内部的转换:隐藏左操作数
    c = c1.operator-(c2);
    c = c1 - c2; 
    c.print();
    return 0;
}

执行结果:
        4 + 6i
        -2 + -2i






int main3_1()
{
    int a = 10, b = 20;
    int cc = a + b;   // 基础数据类型编译器知道运算规则,所以可以直接运算

    Complex c1(1,2), c2(3,4), c;
    c1.print();
    c2.print();

    // Complex 是一个类, c1, c2是类的对象,对象与对象之间的运算规则 编译是不知道,所以无法运算
    // c = c1 + c2;
    // c = add(c1, c2);
    // c = operator+(c1, c2);

    // 运算符重载 赋予运算符一个新的功能  新的运算规则
    // 运算符重载的步骤
    // 1、写出函数名: operator + 要重载的运算符(比如+:operator+, *: operator*  []: operator[])
    // 2、根据运算需要的操作数写出 参数列表,加法需要两个操作数,分别写出左和右操作数:operator+(c1, c2);
    // 3、根据需要写出函数返回值:Complex operator+(const Complex &c1, const Complex &c2)
    c = c1 + c2; // c = operator+(c1, c2);

    // operator+
    // operator+(c1, 10)  ===>  operator+(const Complex &c1, int num)
    // Complex operator+(const Complex &c1, int num)
    c = c1 + 10;
    c.print();

    return 0;
}


执行结果:
  1 + 2i
  3 + 4i
  11 + 2i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值