C++运算符重载

目录

1、运算符重载的意义:

2、重载输出<<运算符:

3、重载输入>>运算符:

 4、重载+运算符:

5、重载==运算符:

6、重载--运算符:

7、重载++运算符:

8、重载&& || 运算符:

9、重载函数调用运算符(函数名()):

10、符号重载的总结:

11、string字符串类的封装 :


1、运算符重载的意义:

赋予运算符新的功能,以适应不同的数据类型。

关键字:operator 运算符:运算符就是我们要重载的运算符,比如 <<输出,>>输入,+,(),【】等。

重载运算符的步骤:

1、分析运算符的操作数的个数;比如cout<<xxx;

2、分析运算符左边的运算对象:自定义对象还是其他,这个就决定了我们是使用全局函数还是成员函数。

左边是其他:使用全局函数(声明为有元)

左边是自定义的对象:可以使用全局函数也可以使用成员函数(推荐,因为只用一个参数)。

2、重载输出<<运算符:

时机:cout<<实例化自定义对象

//重载<<运算符 ,cout<<对象的时候会出现
//左边是其他函数不是自定义函数,在全局区。



#include <stdio.h>
#include<iostream>
using namespace std;
class person
{
    friend ostream &operator<<(ostream &cout,person &ob);
private:
    int age;
    int num;
public:
    person(){}
    person(int a,int n):age(a),num(n){}
    //使用初始化列表

};
//返回值类型是ostream类型的引用,俩个参数一个cout,一个对象
ostream &operator<<(ostream &cout,person  &ob)
{
    cout<<ob.age<<" "<<ob.num;
    //访问类中的数据需要作为友元函数。
    return cout;
}

void test01()
{
    person lucy(10,100);
    person bob(11,110);
    cout << lucy <<" "<< bob << endl;
    //cout<<实例化对象不能输出,重载一下<<
}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

3、重载输入>>运算符:


#include<iostream>
using namespace std;

class Person
{
    friend istream &operator >>(istream &in, Person &ob);

private:
    int age;
    int num;

public:
    Person() {}
    Person(int a, int n):age(a), num(n){}
};
//重载>>运算符
istream &operator >>(istream &in, Person &ob)
{
   in >> ob.age  >> ob.num;
   return in;
}
void test02()
{
    Person lucy;


    cin >> lucy;
    cout << lucy;//这个地方需要重载一个<<运算符
}
int main(int argc, char *argv[])
{
    test02();
    return 0;
}

 4、重载+运算符:

例1:利用全局函数实现+运算符重载

//+运算符在全局重载

#include<iostream>
using namespace std;

class Person
{
    friend Person operator+(const Person &p1,const Person &p2);
    friend ostream &operator <<(ostream &cout,const Person &p);
private:

    int num;

public:
    Person() {}
    Person( int n):num(n){}
};
ostream &operator <<(ostream &cout,const Person &p)
{
    cout<<p.num<<endl;
    return cout;
}

Person operator+(const Person &p1,const Person &p2)
{   
    //定义了临时变量接收,不改变传入的俩个对象的值
    Person temp;
    temp.num = p1.num+p2.num;
    return temp;
}

void test01()
{
   Person p1(10);
   Person p2(20);
   cout<<(p1+p2)<<endl;//+号左边是自定义的,可以全局也可以在类中。
}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

例2:利用成员函数实现+运算符重载

//+运算符在全局重载

#include<iostream>
using namespace std;

class Person
{

    friend ostream &operator <<(ostream &cout,const Person &p);
private:

    int num;

public:
    Person() {}
    Person( int n):num(n){}
    Person operator+(const Person &p2)
    {
        Person temp;
        temp =this->num+p2.num;
        return temp;
    }
};
ostream &operator <<(ostream &cout,const Person &p)
{
    cout<<p.num<<endl;
    return cout;
}

void test01()
{
   Person p1(10);
   Person p2(20);
   cout<<(p1+p2)<<endl;//+号左边是自定义的,可以全局也可以在类中。
   //p1+p2在内部会调用p1.operator+(Person &p2)
}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

5、重载==运算符:

//==重载,返回一个bool类型

#include<iostream>
using namespace std;

class Person
{


private:
    int age;
    int num;

public:
    Person() {}
    Person( int a,int n):age(a),num(n){}
    
    bool operator ==(const Person &p2)
    {
        if(this->age == p2.age && this->num == p2.num)
            return true;
        else 
        {
            return false;
        }
    }
};

void test01()
{
   Person p1(10,20);
   Person p2(20,10);
   if(p1 == p2)
   {
       cout<<"相等"<<endl;
   }else
   {
       cout<<"不相等"<<endl;
   }
}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

6、重载--运算符:

​
//--重载
//前置--没有参数,后置--有个int参数

#include<iostream>
using namespace std;

class Person
{
     friend ostream& operator<<(ostream& cout, const Person& p);
private:
    int age;

public:
    Person() {}
    Person(int a):age(a){}

    Person operator--()
    {
        Person temp;
        temp.age = age-1;
        return temp;

    }
    Person operator--(int)
    {
        Person temp = *this;
        temp.age = age -1;
        return temp;
    }

};
ostream& operator<<(ostream& cout, const Person& p)
{
    cout << p.age << endl;
    return cout;
}

void test01()
{
   Person p1(10);
    cout<<--p1<<endl;
    cout<<p1--<<endl;

}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

​

7、重载++运算符:

//++重载
//前置++没有参数,后置++有个占位参数

#include<iostream>
using namespace std;

class Person
{
     friend ostream& operator<<(ostream& cout, const Person& p);
private:
    int age;
    int num;

public:
    Person() {}
    Person(int a,int num):age(a),num(num){}

    Person operator++()
    {
        Person temp;
        temp.age = age + 1;
        temp.num = num + 1;
        return temp;

    }
    Person operator++(int)
    {
        Person temp = *this;
        temp.age = age + 1;
        temp.num = num + 1;
        return temp;
    }

};
ostream& operator<<(ostream& cout, const Person& p)
{
    cout << p.age <<" "<<p.num<< endl;
    return cout;
}

void test01()
{
   Person p1(10,20);
    cout<<++p1<<endl;
    cout<<p1++<<endl;

}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

8、重载&& || 运算符:

建议不要重载,会破坏短路特性

在C++中&&和||具有短路特性,即在条件判断中,如果能够根据左值来确定整个表达式的结果,则不会执行右侧的条件判断。

重载运算符之后破坏了短路性,因为重载之后的运算符函数必须始终被调用,无论左值是否为真,这意味着无法绕过右侧的条件判断,导致无法实现原有的短路性为。

9、重载函数调用运算符(函数名()):

为算法提供相关策略。

//函数名()重载


#include<iostream>
using namespace std;

class Person
{   
public:
    Person() {}
    Person &operator()(const char* str)
    {
        cout << str << endl;
        //返回值是引用,因为是对原来的实例化对象改变
    }


};
void test01()
{
   Person p1;
   p1("hello");
   //需要重载(),p1虽然是个对象但是可以当初仿函数。
}

int main(int argc, char *argv[])
{
    test01();
    return 0;
}

10、符号重载的总结:

1、=, [ ], ( ) 和  ->  操作符只能通过成员函数进行重载。
2、>>和<<只能通过全局函数配合友元函数进行重载(在类中声明友元函数)。
3、不要重载 && 和 || 操作符,因为无法实现短路规则

                                 运算符                                 建议使用
                        所有的一元运算符                                    成员

                             =, [], () 和 ->

                              必须是成员
                        其他的二元运算符                                   非成员

11、string字符串类的封装 :

mystring.h

#ifndef MY_STRING_H
#define MY_STRING_H
#include <iostream>
//#include <cstring>
using namespace std;
class MyString
{
    friend ostream & operator<<(ostream &out, MyString ob);
    friend istream & operator>>(istream &in, MyString &ob);
private:
    char *str;
    int  size;
public:
    MyString();
    explicit MyString(const char * s);
    MyString(const MyString &ob);
    ~MyString();
    Size();
    char & operator[](int index);
    MyString & operator=(MyString ob);
    MyString & operator=(const char * s);
    MyString  operator+(MyString &ob);
    MyString  operator+(const char * s);
    bool operator>(MyString &ob);
    bool operator>(const char * s);
};

#endif // MY_STRING_H

mystring.cpp

#include "mystring.h"
#include<string.h>
MyString::MyString()
{
    str = new char[0];
    size = 0;
}

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

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

MyString::~MyString()
{
    if(str != NULL){
        delete [] str;
        str = NULL;
    }
}

MyString::Size()
{
    return this->size;
}

char &MyString::operator[](int index)
{
    return str[index];
}

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


    return *this;
}


MyString &MyString::operator=(const char *s)
{
    if(str != NULL)
    {
        delete [] str;
        str = NULL;
    }
    size = strlen(s);
    str = new char[size + 1];
    strcpy(str, s);


    return *this;
}


MyString MyString::operator+(MyString &ob)
{
    MyString tmp;
    tmp.size = size + ob.size;
    tmp.str = new char[tmp.size];
    strcpy(tmp.str, str);
    strcat(tmp.str, ob.str);


    return tmp;
}


MyString MyString::operator+(const char *s)
{
    MyString tmp;
    tmp.size = size + strlen(s);
    tmp.str = new char[tmp.size];
    strcpy(tmp.str, str);
    strcat(tmp.str, s);


    return tmp;
}


bool MyString::operator>(MyString &ob)
{
    if((strcmp(str, ob.str)) > 0)
        return true;
    else
        return false;
}


bool MyString::operator>(const char *s)
{
   if((strcmp(str, s)) > 0)
            return true;
     else
            return false;
}
ostream & operator<<(ostream &out, MyString ob)
{
    out << ob.str;
    return out;
}
istream & operator>>(istream &in, MyString &ob)
{
    if(ob.str != NULL){
        delete [] ob.str;
        ob.str = NULL;
    }
    char buf[1024] = {0};
    in >> buf;
    ob.size = strlen(buf);
    ob.str = new char[ob.size + 1];
    strcpy(ob.str, buf);


    return in;
}

main.cpp

#include <iostream>
#include <mystring.h>

using namespace std;

int main(int argc, char *argv[])
{
    MyString str("hello world");
    //有参构造
    cout << str << endl;
    cout << str.Size() << endl;
    //重载<<

    MyString str1 = str;
    //重载等号
    cout << str1 << endl;

    MyString str2;
    cin >> str2;
    //重载>>
    str2[1] = 'E';
    cout << str2[1] << endl;
    cout << str2 << endl;

    MyString str3;
    MyString str4("haha hehe");
    str3 = str4;
    cout << str3 << endl;

    MyString str5;
    str5 = "xixi heihei";
    cout << str5 << endl;

    MyString str6("hello");
    MyString str7("hihi");

    cout << str6 + str7 << endl;
    cout << str6 + "world" << endl;


    MyString str8("hello");
    MyString str9("world");
    if(str8 > str9){
        cout << "hello大于world";
    }
    else
        cout << "world比hello大";

    if(str9 > "haha")
        cout << "hello大" << endl;
    else
        cout << "haha大" << endl;


    return 0;
}

相关推荐

  1. C++运算符重载

    2023-12-10 22:52:01       41 阅读
  2. C++:运算符重载

    2023-12-10 22:52:01       58 阅读
  3. C++ 运算符重载

    2023-12-10 22:52:01       42 阅读
  4. C++基础——运算符重载

    2023-12-10 22:52:01       45 阅读
  5. C++运算符重载

    2023-12-10 22:52:01       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-10 22:52:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-10 22:52:01       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-10 22:52:01       82 阅读
  4. Python语言-面向对象

    2023-12-10 22:52:01       91 阅读

热门阅读

  1. 【Go自学版】01-基础

    2023-12-10 22:52:01       60 阅读
  2. springboot分页查询

    2023-12-10 22:52:01       57 阅读
  3. Python ipaddress模块介绍

    2023-12-10 22:52:01       57 阅读
  4. 2020蓝桥杯c组纸张大小

    2023-12-10 22:52:01       62 阅读
  5. 生活小记录

    2023-12-10 22:52:01       52 阅读
  6. FCN 模型简介及代码

    2023-12-10 22:52:01       47 阅读
  7. PyQt创建界面

    2023-12-10 22:52:01       55 阅读
  8. 数据管理系统-week12-数据库审计(Database Auditing)

    2023-12-10 22:52:01       53 阅读
  9. kubeadm搭建1.20.7版本k8s

    2023-12-10 22:52:01       50 阅读
  10. CT成像技术—20231205

    2023-12-10 22:52:01       39 阅读