文章标题

运算符的重载

[TOC]
一、重载是否作为类员

  1. 有些运算符只能作为类成员来重载,这种情况下,和定义类成员函数区别不大,比如说=、[]、调用()、和成员访问箭头->
  2. 有些运算符,最好作为类的友元来重载,例如算数操作符、相等操作符,关系操作符等;

二、输入输出运算符
它们只能定义为普通的非成员函数,注意函数的参数例如

// 调用本类输出操作符重载
    friend ostream &operator<<(ostream &out, const OverloadClass &overloadObj);
    // 调用本类输入操作重载
    friend istream &operator>>(istream &in, OverloadClass &overloadObj);

三、+号运算符
最好定义为非成员函数
四、+=运算符
既可以定义为成员函数,也可以定义为非成员函数,但是不能同时使用

    //====================事实正面这两个都可以使用,但是不能同时使用
    // += 操作符重载,类成员函数,需要一个变量
    //OverloadClass operator+=(const OverloadClass &overLoad);
    // += 操作符重载,非类成员函数,
    friend OverloadClass &operator+=(OverloadClass &objLeft, const OverloadClass &objRight);
//
//OverloadClass OverloadClass::operator+=(const OverloadClass&  overLoad)
//{
//  this->productName += overLoad.productName;
//  this->productQuantiy += overLoad.productQuantiy;
//  this->productPrice += overLoad.productPrice;
//  return *this;
//}

// += 操作符重载,非类成员函数,
OverloadClass &operator+=(OverloadClass &objLeft, const OverloadClass &objRight)
{
    objLeft.productName += objRight.productName;
    objLeft.productQuantiy += objRight.productQuantiy;
    objLeft.productPrice += objRight.productPrice;
    return objLeft;
}

五、==运算符
即可定义为类成员函数、也可定义为非类成员函数,并且两种定义可以同时存在,两种定义都存在时

    //=====================注意以下两种方法都可以使用,下面看看两个都存在使用哪个?两个都存在时优先选用类成员函数
    // == 操作符重载
    friend bool operator==(const OverloadClass &objLeft, const OverloadClass &objRight);
    // == 操作符重载,作为成员函数
    bool operator==(const OverloadClass &objToCompare);
// == 操作符重载,前缀表达式
bool operator==(const OverloadClass &objLeft, const OverloadClass &objRight)
{
    if(objLeft.productName != objRight.productName)
        return false;
    if(objLeft.productQuantiy != objRight.productQuantiy)
        return false;
    if(objLeft.productPrice != objRight.productPrice)
        return false;
    return true;
}

// 操作符重载,类成员函数
bool OverloadClass::operator==(const OverloadClass &objToCompare)
{
    if(objToCompare.productName != this->productName)
        return false;
    if(objToCompare.productQuantiy != this->productQuantiy)
        return false;
    if(objToCompare.productPrice != this->productPrice)
        return false;

    return true;
}

六、[]下标运算符
只能定义在类成员函数中
七、++自增运算符
前缀自增运算符和后缀自增运算符怎么区别,一个加一个int参数,在调用的时候传入实参0

  1. 前缀自增运算符
  2. 后缀自增预算符
    //=======================注意前后缀表达式的区别在哪里?
    // ++自增操作符重载,前缀表达式
    int operator++();
    // ++自增操作符重载,后缀表达式
    int operator++(int); // 一般使用0作为实参
int OverloadClass::operator++()
{

    return intVector[++vecIndex];
}

int OverloadClass::operator++(int)
{
    return intVector[vecIndex++];
}

注意上面两个函数的返回值不一样

八、=赋值运算符
赋值操作符重载,注意赋值必须返回对*this的引用
九、*解引用运算符
十、->运算符
在调用p->action中主要看p是对象,还是指针,
C++ Primer中写道:
根据以下三个步骤执行
1、如果p是一个指针,那么直接执行p的成员函数action
2、如果p不是一个指针而是一个对象,那么执行p的->重载函数,相当于p.opeator->()->action,假设m=p.opeator->(),那么判断m是一个指针还是一个对象,从第一步开始执行;
3、其他情况出错
用一段代码来解释一下
GrandFather类

#pragma once
#include <string>
#include <iostream>
using namespace std;
class GrandFather
{
public:
    GrandFather(void);
    ~GrandFather(void);
    void action()
    {
        cout<<"GrandFather's action"<<endl;
    }
    GrandFather *operator->()
    {
        cout<<"进入重载"<<endl;
        return this;
    }
};

Father类

#pragma once
#include <iostream>
#include <string>
#include "GrandFather.h"
using namespace std;
class Father
{
public:
    Father(void);
    ~Father(void);
    GrandFather *pGrandFather;
    GrandFather grandFather;
    void action()
    {
        cout<<"Father's action"<<endl;
    }

    GrandFather *operator->()
    {
        return pGrandFather;
    }

    //GrandFather operator->()
    //{
    //  return grandFather;
    //}
};

Child类

#pragma once
#include <iostream>
#include "Father.h"
using namespace std;
class Child
{
public:
    Child(void);
    ~Child(void);
    Father *pFather;
    Father father;

    void action()
    {
        cout<<"Child's action"<<endl;
    }

    //Father *operator->()
    //{
    //  return pFather;
    //}

    Father operator->()
    {
        return father;
    }

};

运行以下代码

cout<<"->操作符重载"<<endl;
                Child *pChild, child;
                pChild = new Child;
                pChild->action();   // 执行action函数
                child->action();    // 先执行Child重载函数->然后得到一个Father对象执行它的->函数,
                //得到一个GrandFather对象指针,执行Grandfather的函数,关键是看是对象还是对象的指针

得到的结果是

Child’s action
GrandFather’s action

注意,小弟有个问题请教在Father类中,
GrandFather *operator->()
{
return pGrandFather;
}

pGrandFather没有分配内存空间,为什么没有报内存泄露的错,请大神指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值