C++杂讲 运算符重载

目录

知识点1【运算符重载概述】

知识点2【可重载的运算符】

知识点3【运算符重载的步骤】

知识点4【重载运算符<<】

知识点5【重载>>运算符】

知识点6【重载==运算符】

知识点7【自增自减(++/--)运算符重载】

 知识点8【重载=赋值运算符】

 知识点9【重载 函数调用运算符 () 】

知识点10【不要重载&& || 用户没办法实现短路特性 】(重要)

知识点11【不能重载的运算符】

知识点12【运算符重载案例】


知识点1【运算符重载概述】

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

比如:重载+运算符完成"lucy"+“bob”拼接

void operator+(参数1,参数2)
{
    
}

知识点2【可重载的运算符】

知识点3【运算符重载的步骤】

运算符重载分析步骤:

1、分析运算符左边的运算对象。如果不是自定义类的对象,只能用全局函数 实现运算符重载

        全局函数的第一参数左边的运算对象

        全局函数的第二个参数右边的运算对象

2、分析运算符左边的运算对象.如果是自定义类的对象,可以用全局函数、成员函数 实现运算符重载。

        全局函数的第一参数左边的运算对象

        全局函数的第二个参数右边对象

成员函数:可以省略一个参数,只需要将运算符右边的对象 传递到成员函数中。(推荐)

知识点4【重载运算符<<】

#include <iostream>
#include <string>
using namespace std;
class Person
{
    friend ostream& operator<<(ostream &out, Person &ob);
private:
    int num;
    string name;
    int age;
public:
    Person(){}
    Person(int num, string name, int age)
    {
        this->num = num;
        this->name = name;
        this->age = age;
    }
    void showPerson(void)
    {
        cout<<"学号:"<<num<<", 姓名:"<<name<<", 年龄:"<<age<<endl;
    }
};

//全局友元函数实现运算符重载
ostream& operator<<(ostream &out, Person &ob)
{
    out<<"学号:"<<ob.num<<", 姓名:"<<ob.name<<", 年龄:"<<ob.age<<endl;
    return out;
}

int main(int argc, char *argv[])
{
    Person ob1(100,"lucy", 18);
    Person ob2(101,"bob", 19);

    cout<<ob1<<ob2<<endl;// operator<<(cout,ob1);
    return 0;
}

知识点5【重载>>运算符】

#include <iostream>
#include <string>
using namespace std;
class Person
{
    friend ostream& operator<<(ostream &out, Person &ob);
    friend istream& operator>>(istream &in, Person &ob);
private:
    int num;
    string name;
    int age;
public:
    Person(){}
    Person(int num, string name, int age)
    {
        this->num = num;
        this->name = name;
        this->age = age;
    }
    void showPerson(void)
    {
        cout<<"学号:"<<num<<", 姓名:"<<name<<", 年龄:"<<age<<endl;
    }
};

//全局友元函数实现运算符重载
ostream& operator<<(ostream &out, Person &ob)
{
    out<<"学号:"<<ob.num<<", 姓名:"<<ob.name<<", 年龄:"<<ob.age<<endl;
    return out;
}

//全局友元函数实现运算符重载
istream& operator>>(istream &in, Person &ob)
{
    in>>ob.num>>ob.name>>ob.age;
    return in;
}

int main(int argc, char *argv[])
{
    Person ob1(100,"lucy", 18);
    Person ob2(101,"bob", 19);

    cout<<ob1<<ob2<<endl;// operator<<(cout,ob1);

    Person ob3;
    cin>>ob3;
    cout<<ob3;
    return 0;
}

知识点6【重载==运算符】

#include <iostream>
#include <string>
using namespace std;
class Person
{
    friend ostream& operator<<(ostream &out, Person &ob);
    friend istream& operator>>(istream &in, Person &ob);
    //friend bool operator==(Person &ob1, Person &ob2);
private:
    int num;
    string name;
    int age;
public:
    Person(){}
    Person(int num, string name, int age)
    {
        this->num = num;
        this->name = name;
        this->age = age;
    }
    void showPerson(void)
    {
        cout<<"学号:"<<num<<", 姓名:"<<name<<", 年龄:"<<age<<endl;
    }

    //成员函数完成==重载
    bool operator==(Person &ob)
    {
        if(num==ob.num && name==ob.name && age==ob.age)
            return true;
        else
            return false;
    }

};

//全局友元函数实现运算符重载
ostream& operator<<(ostream &out, Person &ob)
{
    out<<"学号:"<<ob.num<<", 姓名:"<<ob.name<<", 年龄:"<<ob.age<<endl;
    return out;
}

//全局友元函数实现运算符重载
istream& operator>>(istream &in, Person &ob)
{
    in>>ob.num>>ob.name>>ob.age;
    return in;
}

#if 0
//全局友元函数 实现==重载
bool operator==(Person &ob1, Person &ob2)
{
    if(ob1.num==ob2.num && ob1.name==ob2.name && ob1.age==ob2.age)
        return true;
    else
        return false;
}
#endif

int main(int argc, char *argv[])
{
    Person ob1(100,"lucy", 18);
    Person ob2(101,"bob", 19);

    cout<<ob1<<ob2<<endl;// operator<<(cout,ob1);

    Person ob3;
    cin>>ob3;
    cout<<ob3;

    //ob1.operator==(ob2);
    if(ob1 == ob2)
    {
        cout<<"相等"<<endl;
    }
    else
    {
        cout<<"不相等"<<endl;
    }
    return 0;
}

知识点7【自增自减(++/--)运算符重载】

当编译器看到 ++a   (前置++),它就调用operator++(a),

当编译器看到 a++   (后置++),它就会去调用operator++(a,int)

全局函数实现:

        ++ob ------------->operator++(ob)

        ob++ ------------->operator++(ob, int)

成员函数实现:

        ++ob ------------->ob.operator++()

        ob++ ------------->ob.operator++(int)

#include <iostream>

using namespace std;
class Data
{
    friend ostream& operator<<(ostream &out, Data ob);
private:
    int a;
    int b;
public:
    Data(){}
    Data(int a, int b):a(a),b(b){}

    //重载ob++  先使用  后加减
    Data operator++(int)
    {
        //保存++之前的值
        Data tmp = *this;

        //进行自增
        a = a+1;
        b = b+1;

        return tmp;//返回++之前的值
    }

    //重载++ob  先加减  后使用
    Data operator++()
    {
        //先加减
        a=a+1;
        b=b+1;

        //再使用
        return *this;
    }

};
ostream& operator<<(ostream &out, Data ob)
{
    out<<"a="<<ob.a<<", b="<<ob.b<<endl;
    return out;
}

int main(int argc, char *argv[])
{
    Data ob1(10,20);
    cout<<ob1<<endl;
    cout<<ob1++<<endl;
    cout<<ob1<<endl;

    Data ob2(100,200);
    cout<<ob2<<endl;
    cout<<++ob2<<endl;
    cout<<ob2<<endl;
    return 0;
}

 知识点8【重载=赋值运算符】

(类中有指针成员 才需要重载=)

如果类中没有指针成员 相同类型的对象 可以直接=赋值(浅拷贝)

如果类中有指针成员 相同类型的对象 必须重载=(深拷贝)

#include<string.h>
class Data2
{
public:
    char *str;//指针成员
public:
    Data2(){}
    Data2(char *str)
    {
        this->str = new char[strlen(str)+1];
        strcpy(this->str, str);
    }
    ~Data2()
    {
        if(str != NULL)
        {
            delete [] str;
            str=NULL;
        }
    }
    //重载=
    Data2& operator=(Data2 &ob)
    {
        cout<<"重载="<<endl;
        this->str = new char[strlen(ob.str)+1];
        strcpy(this->str, ob.str);
        return *this;
    }
};
void test02()
{
    Data2 ob1("hello world");
    Data2 ob2;
    Data2 ob3;
    ob3 = ob2 = ob1;
    cout<<ob2.str<<endl;
    cout<<ob3.str<<endl;
}

总结:如果类中有指针成员

必须实现拷贝构造(深拷贝)、必须实现析够函数(释放指针成员所指向的空间)、必须重载=运算符(深拷贝)

 知识点9【重载 函数调用运算符 () 】

class Print
{
public:
    void operator()(char *str)
    {
        cout<<str<<endl;
    }
};
void test03()
{
    Print ob;
    ob.operator ()("hello world");

    //仿函数(本质 不是函数  只是像函数调用)
    //对象名 与 ()结合   触发了operator()调用   (本质)
    ob("hello beijing");

    //Print()是Print类的匿名对象
    Print()("hello qf");
}

8、不要重载&& || 用户没办法实现短路特性 (重要)

知识点10【不要重载&& || 用户没办法实现短路特性 】(重要)

知识点11【不能重载的运算符】

 

知识点12【运算符重载案例】

mystring.h

#ifndef MYSTRING_H
#define MYSTRING_H
#include<iostream>
using namespace std;

class MyString
{
    friend ostream& operator<<(ostream &out, MyString ob);
private:
    char *str;
    int size;
public:
    MyString();
    MyString(char *str);
    MyString(const MyString &ob);
    ~MyString();

    //获取字符串的长度
    int getSize(void);
    //获取字符
    char& operator[](int pos);
    char& at(int pos);

    //重载赋值运算符=
    MyString& operator=(MyString &ob);
    MyString& operator=(char *str);

    //重载赋值运算符+=
    MyString& operator+=(MyString &ob);
    MyString& operator+=(char *str);

    //重载+运算符
    MyString operator+(MyString &ob);
   // MyString operator+(char *str);

    bool operator>(MyString &ob);

};


#endif // MYSTRING_H

myString.cpp

#include "mystring.h"
#include<string.h>
#include<iostream>
using namespace std;
MyString::MyString()
{
    str=NULL;
    size=0;
    cout<<"无参构造"<<endl;
}

MyString::MyString(char *str)
{
    size = strlen(str);
    this->str = new char[size+1];
    strcpy(this->str, str);
    cout<<"有参构造"<<endl;
}

MyString::MyString(const MyString &ob)
{
   size = ob.size;
   str = new char[size +1];
   strcpy(str, ob.str);
   cout<<"拷贝构造函数"<<endl;
}

MyString::~MyString()
{
    if(str != NULL)
    {
        delete [] str;
        str = NULL;
    }
    cout<<"析够函数调用"<<endl;
}

int MyString::getSize()
{
    return size;
}

char& MyString::operator[](int pos)
{
    if(pos>=0 && pos<size)
    {
        return str[pos];
    }
    else
    {
        cout<<"坐标无效"<<endl;
    }
}

char &MyString::at(int pos)
{
    if(pos>=0 && pos<size)
    {
        return str[pos];
    }
    else
    {
        cout<<"坐标无效"<<endl;
    }
}

MyString &MyString::operator=(MyString &ob)
{
    //ob1 = ob
    //先释放ob1.str指向的堆区空间
    if(str != NULL)
    {
        delete [] str;
        str=NULL;
    }

    size = ob.size;
    str = new char[size+1];
    strcpy(str, ob.str);

    return *this;
}

MyString &MyString::operator=(char *str)
{
    //先释放ob1.str指向的堆区空间
    if(this->str != NULL)
    {
        delete [] this->str;
        this->str=NULL;
    }

    size = strlen(str);
    this->str = new char[size+1];
    strcpy(this->str, str);

    return *this;
}

MyString& MyString::operator+=(MyString &ob)
{
    if((str==NULL) && (ob.str != NULL))
    {
        size = ob.size;
        str = new char[size+1];
        memset(str, 0,size+1);
        strcpy(str, ob.str);

        //记得返回
    }
    else if((str != NULL) && (ob.str == NULL))
    {
        //记得返回
    }
    else if((str == NULL) && (ob.str == NULL))
    {
        cout<<"全为NULL无法拼接"<<endl;
        //记得返回
    }
    else if((str != NULL) && (ob.str != NULL))
    {
        //str7 += str8
        //新空间的大小
        size = size+ob.size;
        char *tmp_str = new char[size+1];
        //清空新空间的内容
        memset(tmp_str, 0, size+1);

        strcpy(tmp_str, str);
        strcat(tmp_str, ob.str);

        //释放str指向的空间
        delete [] str;
        str = tmp_str;
        //记得返回
    }

    return *this;
}

MyString &MyString::operator+=(char *str)
{
    if(this->str == NULL)
    {
        size = strlen(str);
        this->str = new char[size+1];
        memset(this->str, 0, size+1);
        strcpy(this->str, str);
    }
    else if(this->str != NULL)
    {
        size = size+strlen(str);
        char *tmp_str = new char[size+1];
        memset(tmp_str, 0, size+1);
        strcpy(tmp_str, this->str);
        strcat(tmp_str, str);

        //释放this->str指向的旧空间
        delete [] this->str;
        this->str = tmp_str;
    }
    return *this;
}

MyString MyString::operator+(MyString &ob)
{
    if((this->str==NULL) && (ob.str == NULL))
    {
        cout<<"全空无法进行+运算"<<endl;
        return *this;
    }
    else if((this->str!=NULL) && (ob.str == NULL))
    {
        return *this;
    }
    else if((this->str==NULL) && (ob.str != NULL))
    {
        return ob;
    }
    else if((this->str!=NULL) && (ob.str != NULL))
    {
        char *buf=new char[size+ob.size+1];
        memset(buf, 0, size+ob.size+1);
        strcpy(buf,this->str);
        strcat(buf, ob.str);

        MyString tmp(buf);

        delete [] buf;

        return tmp;
    }
}

bool MyString::operator>(MyString &ob)
{
    if((str != NULL) && (ob.str != NULL) )
    {
        if(strcmp(str, ob.str)>0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        cout<<"存在NULL字符串无法比较大小"<<endl;
    }
    return false;
}

//全局函数重载<<运算符
ostream& operator<<(ostream &out, MyString ob)
{
    cout<<ob.str;
    return out;
}

main.cpp

#include <iostream>
#include "mystring.h"
using namespace std;

int main(int argc, char *argv[])
{
#if 0
    MyString str1("hello");
    cout<<"str1的长度="<<str1.getSize()<<endl;
    cout<<str1<<endl;

    //获取str1的某个字符
    str1[2] = 'W';
    cout<<str1[2] <<endl;
    str1.at(3)='H';
    cout<<str1<<endl;

    //对象赋值
    MyString str2("hello");
    MyString str3("world");
    MyString str4("hehe");
    str4 = str3 = str2;
    cout<<str4<<endl;

    //字符串 给对象赋值
    MyString str5;
    MyString str6;

    str6 = str5 = "hello";
    cout<<str6<<endl;

    MyString str7("hello");
    MyString str8("world");

    str7 += str8;
    cout<<str7<<endl;

    MyString str9;

    str9+="world";
    cout<<str9<<endl;
#endif
    MyString str10("hello");
    MyString str11("world");
    MyString str12("hehe");


    cout<<(str10+str11+str12)<<endl;

    if(str11 > str12)
    {
        cout<<"大于"<<endl;
    }
    else
    {
        cout<<"不大于"<<endl;
    }

    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值