PoEdu培训 C++班 第七课 类和对象(5) 运算符重载
文章类别: 培训笔记 0 评论

PoEdu培训 C++班 第七课 类和对象(5) 运算符重载

文章类别: 培训笔记 0 评论

类和对象(5)

运算符重载

语法: operator运算符
new 和 delete的重载为: operator new 和 operator delete
基本上, 常见的运算符都可以重载:
算术运算符: =, -, *, /, %, ++, --
位操作运算符: —, |, ~, ^, <<, >>
逻辑运算符: !, &&, ||
比较运算符: >, <, >=, <=, ==, !=
赋值运算符: =, +=, -=, *=, %=, \=, ^=, <<=, >>=;
其他运算符: [], (), ->, ', new, delete, new[], delete[], ->*, .

&(取地址运算符) 可以重载, 并且默认生成, 运算符返回的是this指针
*(解指针运算符) 可以重载, 并且默认生成
=(赋值运算符) 可以重载, 并且默认生成, 它就是我们默认的赋值函数

并不是所有的运算符都可以重载

无法重载的运算符:
  1. 域运算符 ::
  2. 三目运算符(条件运算符) ?:
  3. 直接成员访问运算符(类属关系运算符) .
  4. sizeof运算符
  5. 类成员指针运算符 .*

不是所有的运算符都需要重载, 要根据自己的业务来实现运算符的重载

运算符扩展阅读

微软MSDN C++运算符(VS2015)
微软MSDN C++运算符(VS2017)

回顾总结

重载运算符的方式

成员函数形式
友元函数形式

友元

友元是一种特定的机制.
使用friend关键字
它标记的函数不属于当前类, 不能被类对象使用.->进行访问, 也不能访问类成员.
但是, 在需要进行访问的时候, 友元函数是可以使用的.
友元主要用于运算符的重载

重载运算符练习

#include <iostream>

using namespace std;

// 模拟int
class Integer
{
private:
    int _iNum = 0;

public:
    Integer(int iNum = 0) : _iNum(iNum)
    {
    }

    // 重载运算符=, 实现直接接受数字  
    // Integer i = 10;
    Integer& operator=(int iNum)
    {
        _iNum = iNum;
        return *this;
    }

    Integer& operator=(const Integer& other)
    {
        _iNum = other._iNum;
        return *this;
    }

    // 重载+=运算符, 实现直接+=
    // Integer i = 10; i += 20;
    Integer& operator+=(const int iNum)
    {
        _iNum += iNum;
        return *this;
    }

    // 重载+运算符, 实现直接 +
    // 需要注意返回值哦
    // Integer i = 10, j = 0; j = i + 10;
    Integer operator+(const int iNum)
    {
        Integer tmp = _iNum;
        tmp._iNum += iNum;
        return tmp;
    }

    // 重载+运算符, 实现 XX + 
    // 它不属于类对象内部的函数
    // 它不能使用成员变量
    // Integer i = 10, j = 0; j = 10 + i;
    friend Integer operator+(int iNum, const Integer& me)
    {
        Integer tmp = me._iNum;
        tmp._iNum += iNum;
        return tmp;
    }

    // 它不属于类对象内部的函数
    // 它不能使用成员变量
    // 重载+运算符, 实现 += 10
    // Integer i = 10; i += 20;
    friend Integer& operator+=(int iNum, Integer& me)
    {
        me._iNum += iNum;
        return me;
    }


    // 只能这样才能区分 前++和 后++
    // 这是前++
    // Integer i = 10; ++i;
    Integer& operator++()
    {
        ++_iNum;
        return *this;
    }

    // 这个int参数没有用, 只是把后++当做双目运算符来使用
    // 这是后++
    // Integer i = 10; i++;
    Integer operator++(int)
    {
        Integer tmp = *this;
        _iNum++;
        return tmp;
    }

    // 重载==
    bool operator==(const Integer& other) const
    {
        return _iNum == other._iNum;
    }


    // 重载<< 实现cout直接 << 
    // Integer i = 10; std::cout << i << std::endl;
    friend std::ostream& operator<<(std::ostream& os, const Integer& me)
    {
        os << me._iNum;
        return os;
    }

    // lhs  rhs 左手边的值 右手边的值
    // 重载>> 实现cint直接赋值
    // Integer i = 0; std::cin >> i;
    friend std::istream& operator >> (std::istream& lhs, Integer& rhs)
    {
        lhs >> rhs._iNum;
        return lhs;
    }

    // new  delete还没重载

    int GetNum()
    {
        return _iNum;
    }

};

int main()
{
    using namespace std;

    // 实现一个Integer的版本来进行对比
    int n1 = 10, n2 = 20;
    cout << n1 << "  " << n2 << endl;
    n1 = n2 = 100;
    cout << n1 << "  " << n2 << endl;
    n1 = 100 + n2 + 1000;
    cout << n1 << "  " << n2 << endl;

    n2 = n1++;
    cout << n1 << "  " << n2 << endl;
    n2 = ++n1;
    cout << n1 << "  " << n2 << endl;

    cout << "====================================" << endl;

    Integer cn1 = 10, cn2 = 20;
    cout << cn1 << "  " << cn2 << endl;
    cn1 = cn2 = 100;
    cout << cn1 << "  " << cn2 << endl;
    cn1 = 100 + cn2 + 1000;
    cout << cn1 << "  " << cn2 << endl;

    cn2 = cn1++;
    cout << cn1 << "  " << cn2 << endl;
    cn2 = ++cn1;
    cout << cn1 << "  " << cn2 << endl;

    return 0;
}

小知识

class Integer{};

// 这样会返回一个Integer类的拷贝, 在外部使用完成后进行析构.
return Integer(10);
// 这样会返回当前Integer的一个引用, 在出了函数后就进行析构.
return Integer&;

// 可以通过 operator=, 构造函数, 析构函数 进行输出语句来进行观察研究 

如有错误,请提出指正!谢谢.

回复