C++ operator 重载

本文详细探讨了C++中的运算符重载原则,包括何时选择成员函数和非成员函数实现。通过一个自定义`node`类展示了如何重载赋值、复合赋值、下标、调用、成员访问、自增、自减、解引用等运算符。同时,文章还提供了输入输出流的重载示例,并在实践中应用这些运算符。
摘要由CSDN通过智能技术生成

1 重载的运算符的本质是函数
2 我们不能重载内置类型的算数运算符
3 重载运算符应被定义为普通非成员函数还是成员函数规则,如下:

  • 赋值(=),下标([]),调用(()),和成员访问箭头(->)运算符必须是成员
  • 复合赋值运算符一般应该是成员,但是并非必须~
  • 改变对象状态的运算符或者与给定类型密切相关的运算符,自增++,自减–,解引用*,成员访问运算符.通常应该是成员函数
  • 具有对称性的运算符可以转换到任意一端的运算对象,例如算术,相等性,关系和位运算符等,因此他们通常应该是普通的非成员函数
#include <fstream>
#include <iostream>
#include <istream>
#include <ostream>

class node{
public:
    int id;
    int spend;
    
    // 构造
    node(){
        id = 0;
        spend = 0;
        for(int i = 0;i < 10; ++i){
            nums[i] = i;
        }
    }

    // 我们应该避免除了向bool显式转换以外的转换
    operator bool() const{
        if(id != 0)
            return true;
        return false;
    }

    node operator += (node no){
        node temp;
        temp.spend = this->spend + no.spend;
        return temp;
    }
    node operator -= (node no){
        node temp;
        temp.spend = this->spend - no.spend;
        return temp;
    }
    int operator [] (int num){
        return this->nums[num];
    }
    // 虽然此处未返回引用,但是由于返回了指针,因此我们的修改也会在内存中生效
    int* operator *(){
        return (*this).nums;
    }
    // c++ pirmer 中提到重载的->必须返回类的指针或者自定义了箭头运算符的某个类的对象,但是我们这里返回的显然与此描述不符
    int* operator -> (){
        return this->nums;
    }
    int operator ()(){
        return id;
    }
    // 前置
    node& operator ++(){
        this->id ++;
        return *this;
    }
    // 后置
    node operator ++(int){
        node no = *this;
        this->id ++;
        return no;
    }
private:
    int nums[10];



    // 当我们把一个运算符定义为成员函数时,他的左侧对象类型应与重载该符号的类的类型相同
    
     
};

// 非成员函数类型的重载
// 正常情况下我们应该只输入输出,不进行格式控制,这里算是一个反面教材
std::istream& operator >> (std::istream &in,node &no){
    std::cout << "please input node id:";
    in >> no.id;
    std::cout << "please input node spend:";
    in >> no.spend;
    return in;
}
// 输出时node 不必为引用类型,否则不可以cout << no1 + no2 这种样式输出
// 因为no1 + no2运算后为一个友值,对于一个右值自然是不能引用的
std::ostream& operator << (std::ostream &out,node no){
    std::cout << no.id << " ";
    std::cout << no.spend;
    return out;
}
node operator + (node no1,node no2){
    node temp;
    temp.spend += no1.spend;
    temp.spend += no2.spend;
    return temp;
}
node operator - (node no1,node no2){
    node temp;
    temp.spend = no1.spend - no2.spend;
    return temp;
}
bool operator == (node no1,node no2){
    if(no1.id == no2.id)
        return true;
    return false;
}
bool operator != (node no1,node no2){
    if(no1.id != no2.id)
        return true;
    return false;
}

int main(){
    node no1,no2;
    // 如果把node的输入输出定义为成员函数,则如下:
    // no1 >> cin;      因为成员函数运算符的左侧为他自身,唯一的参数为运算符右侧的符号

    // 输入输出
    std::cin >> no1 >> no2;
    std::cout << no1 << std::endl << no2 << std::endl;
    // +
    std::cout << no1+no2 << std::endl;
    // -
    std::cout << no1-no2 << std::endl;
    
    // ==
    node no3 = no1 + no2;
    if(no3 == no1 + no2)
        std::cout << "True" << std::endl;

    // []
    std::cout << no1[3] << std::endl;

    // ++
    node no4 = ++ no1;
    std::cout << no4 << std::endl;
    no4 = no1 ++;
    std::cout << no4 << std::endl;

    // *
    (*no1)[5] = 10;
    std::cout << (*no1)[5] << " " ;
    // ->     
    (*no1)[5] = 5;
    std::cout << no1.operator->()[5] << std::endl;

    // () 与构造函数有区别
    std::cout << no2.id << " " << no2() << std::endl;

    // bool()
    std::cout << no2 << " " << (bool)no2 << std::endl;

    return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值