操作重载

重载的运算符是具有特殊名字的函数。它们的名字由关键字operator和其后要定义的运算符号共同组成。当一个重载的运算符是成员函数时,this绑定到左侧运算对象。成员运算符函数的参数数量比运算对象少一个。
不能被重载的运算符有(::) (.* )(. )(?:)
不应该被重载的运算符: 逻辑运算符,逗号运算符,取地址运算符


选做成员函数的运算符:
=,[ ],( ), ->,
符合赋值+=,-=.. ,
++,–,*(解引用) 改变对象的状态或与给定类型密切相关的运算符


选做非成员函数的运算符:
算数+,-,*,/…
相等性== ,!=
关系 >,<,>=,<=..
位运算符 ^, |, &


重载输入和输出运算符:
必须为非成员函数,输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应该打印换行符。输入运算符必须处理输入可能失败的情况,而输出运算符不需要。

#include <string>
class A
{
    friend std::ostream& operator<<(std::ostream& os,const A &a);
    friend std::istream& operator>>(std::istream& is,A &a);
public:
    A(int a=10,std::string s="initial"):value(a),s(s){}
private:
    int value;
    std::string s;
};
std::ostream& operator<<(std::ostream& os,const A &a)
{
    os<<a.value<<a.s;
    return os;
}
std::istream& operator>>(std::istream& is,A &a)
{
    is>>a.value>>a.s;
    if(!is)
    {
        a=A();
        std::cerr<<"invalid input!\n";
    }
    return is; 
}
int main()
{
    A a;
    std::cin>>a;
    std::cout<<a<<std::endl;
    return 0;
}

重载相等与不相等运算符:
非成员函数,需具有传递性,定义了其中一个一般需要定义另一个,而通常运算符的一个应该把工作委托给另一个。

#include <iostream>
#include <string>
class A
{
    friend bool operator==(const A& a1,const A &a2);
    friend bool operator!=(const A& a1,const A &a2);
public:
    A(int a=10,std::string s="initial"):value(a),s(s){}
private:
    int value;
    std::string s;
};
bool operator==(const A& a1,const A &a2)
{
    return a1.value==a2.value&&a1.s==a2.s;
}
bool operator!=(const A& a1,const A &a2)
{
    return !(a1==a2);
}
int main()
{
    A a1,a2(11,"apple"),a3;
    std::cout<<(a1==a2)<<std::endl;
    std::cout<<(a1==a3)<<std::endl;
    std::cout<<(a1!=a2)<<std::endl;
    std::cout<<(a1!=a3)<<std::endl;
    return 0;
}

重载下标运算符:
成员函数,如果一个类包含下标运算符,则它通常会定义两个版本,一个返回普通引用,另一个类返回常量引用。

#include <iostream>
#include <string>
class A
{
public:
    A():value(new int[8]){}
    int& operator[](std::size_t n){return value[n];}
    const int &operator[](std::size_t n)const {return value[n];}
private:
    int *value;
};
int main()
{
    A a;
    a[5]=8;
    std::cout<<a[5]<<std::endl;
    const A a1;
    //a1[2]=1;//错误
    return 0;
}

重载递增和递减运算符:
成员函数,有前置和后置版本,前置返回引用,后置返回值。

#include <iostream>
class A
{
    friend std::ostream& operator<<(std::ostream& os,const A &a);
public:
    A(int a=0):value(a){};
    A & operator++(){
        value++;
        return *this;
    }//前置版本++ 
    A operator++(int){
        int tmp=value;
        value++;
        return *this;
    }//后置版本++
    A &operator--(){
        value--;
        return *this;
    }//前置版本-- 
    A operator--(int){
        int tmp=value;
        value--;
        return *this;
    }//后置版本--
private:
    int value;
};
std::ostream& operator<<(std::ostream& os,const A &a)
{
    os<<a.value;
    return os;
}
int main()
{
    A a(8);
    ++a;
    std::cout<<a<<std::endl;//9 
    --a;
    std::cout<<a<<std::endl;//8
    a.operator++();
    std::cout<<a<<std::endl;//9
    a.operator--();
    std::cout<<a<<std::endl;//8
    return 0;
}

重载成员访问运算符,即*和->
成员函数(不总是),*返回对象的引用,->返回对象的地址。

#include <iostream>
class A
{
public:
    A(int a=0):value(a){};
    A & operator++(){
        value++;
        return *this;
    }//前置版本++ 
    A operator++(int){
        int tmp=value;
        value++;
        return *this;
    }//后置版本++
    A &operator--(){
        value--;
        return *this;
    }//前置版本-- 
    A operator--(int){
        int tmp=value;
        value--;
        return *this;
    }//后置版本--
    int value;
};
class A_ptr
{
public:
    A_ptr(A &a):a_ptr(&a){};
    A &operator*() const{return *a_ptr;}
    A *operator->() const {return a_ptr;} 
    A *a_ptr;
};
int main()
{
    A a(8);
    A_ptr ap(a);
    std::cout<<ap->value<<std::endl;//8
    ap->operator++(); //++a 
    std::cout<<ap->value<<std::endl;//9
    std::cout<<(*ap).value<<std::endl;//9
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值