c++基础知识学习---第五天

本片博客是作者在学习c++的过程中的笔记记录,希望和各位读者一起学习交流

运算符重载

  1. 概念
    运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
  2. 基础
    1. 运算符函数是一种特殊的成员函数或者友元函数
    2. 成员函数的语法形式:
      类型 类名::operator op(参数表)
      {
        //操作
      }
    3. 一个运算符被重载后,原有的意义没有失去,只是定义了相对特定类的一个新运算符
    4. 例如:
      1. //全局函数 完成 + 操作符 重载
        Complex operator+(Complex &c1,Complex &c2);
      2. //类成员函数 完成 - 操作符 重载
        Complex operator-(Compelx &c2);
  3. 本质
    运算符重载的本质是函数调用
  4. 用成员函数或友元函数重载运算符
    1. 二元运算符
        ObjectL op ObjectR
      重载为成员函数,解释为:
        ObjectL.operator op(ObjectR)
      左操作数由ObjectL通过this指针传递,右操作数由参数ObjectR传递
      重载为友元函数,解释为:
        operator op(ObjectL,ObjectR)
      左右操作数都由参数传递
    2. 一元运算符
        Object op 或 op Object
      重载为成员函数,解释为:
        Object.operator op()
      操作数由对象Object通过this指针隐含传递
      重载为友元函数,解释为:
        operator op(Object)
      操作数由参数表Object提供
      eg:重载前置++、后置++运算符
      1. 重载前置++:
        成员函数的重载: 函数类型& operator++()
        友元函数的重载:friend 函数类型& operator++(类型& )
      2. 后置++运算符的重载方式:
        成员函数的重载:函数类型 operator++(int)
        友元函数的重载:friend 函数类型 operator++(类型&, int)

      注意:重载后置++的返回的是右值,因此返回类型不能加引用

       在这里插入图片描述

上述程序是重载后置++而且是返回对象的引用,会引用程序宕机,因为tmp是一个临时变量,当后置++运算结束后,tmp就会消失,因此必须返回一个对象,也即会返回一个匿名对象。
  1. 利用友元函数重载输入、输出流(函数返回值充当左值,需要返回一个引用)

    1. 基础知识:
      1. istream和ostream是c++预定义流类
      2. cin是istream的对象,cout是ostream的对象
      3. 运算符<<由ostream重载为插入操作,用于输出基本类型数据
      4. 运算符>>由istream重载为提取操作符,用于输入基本类型数据
    2. 输出流
      函数原型:
      friend ostream & operator<<(ostream &out,Test &test)
      函数定义:
      ostream & operator<<(ostream &out,Test &test)
      {
      out << test.a << endl;
      return out;
      }
    3. 输入流
      函数原型:
      friend istream & operator>>(istream &in,Test &test)
      函数定义:
      istream & operator>>(istream &in,Test &test)
      {
      in>>test.a;
      return in;
      }
    4. c++中不能用友元函数重载的运算符:=、()、[]、->
  2. 重载操作符“=”解决赋值浅拷贝问题
    要点:

    1. 先释放内存
    2. 返回一个引用
    3. =操作符,结合顺序是从右向左
      在这里插入图片描述
  3. 重载运算符[]
    函数原型:
    int & operator[](int i);
    类型 类::operator[](类型);

  4. 重载运算符()
    函数原型:
    double operator()(double x,double y);
    类型 类::operator()(表达式);

  5. &&、||运算符
    这两个运算符不进行重载,因为运算符重载是经过函数调用,但是不可以实现&&、||本身的短路原则

  6. 重载string案例(案例来自于C++ Primer Plus 第6版 P442
    string.h

    
    	#pragma once
    	
    	#include<iostream>
    	
    	using std::ostream;
    	using std::istream;
    	
    	class MyString
    	{
    	private:
    		char *str;
    		int len;
    		
    	public:
    		static const int CINLIM = 80;
    	
    		MyString(const char *);
    		MyString();
    		MyString(const MyString &);
    		~MyString();
    	
    		MyString & operator=(const MyString );
    		MyString & operator=(const char *);
    		char & operator[](int i);
    		const char & operator[](int i) const;
    	
    		friend bool operator<(const MyString &st1, const MyString &st2);
    		friend bool operator>(const MyString &st1, const MyString &st2);
    		friend bool operator==(const MyString &st1, const MyString &st2);
    		friend ostream & operator<<(ostream & os, const MyString &st);
    		friend istream & operator>>(istream & is, const MyString &st);
    	
    	};
    
    

    string.cpp

    	#define _CRT_SECURE_NO_WARNINGS
    	#include "string.h"
    	#include<cstring>
    	
    	using std::cin;
    	using std::cout;
    	
    	MyString::MyString(const char * s)
    	{
    		len = std::strlen(s);
    		str = new char[len + 1];
    		std::strcpy(str, s);
    	}
    	
    	MyString::MyString()
    	{
    		len = 4;
    		str = new char[1];
    		str[0] = '\0';
    	}
    	
    	MyString::MyString(const MyString & st)
    	{
    		len = st.len;
    		str = new char[len + 1];
    		std::strcpy(str, st.str);
    	}
    	
    	MyString::~MyString()
    	{
    		delete[]str;
    	}
    	
    	MyString & MyString::operator=(const MyString st)
    	{
    		if (this == &st)
    			return *this;
    		delete[]str;
    		len = st.len;
    		str = new char[len + 1];
    		std::strcpy(str, st.str);
    		return *this;
    	}
    	
    	MyString & MyString::operator=(const char *s)
    	{
    		delete[]str;
    		len = std::strlen(s);
    		str = new char[len + 1];
    		std::strcpy(str, s);
    		return *this;
    	}
    	
    	char & MyString::operator[](int i)
    	{
    		return str[i];
    	}
    	
    	const char & MyString::operator[](int i) const
    	{
    		return str[i];
    	}
    	
    	bool operator<(const MyString & st1, const MyString & st2)
    	{
    		return (std::strcmp(st1.str, st2.str) < 0);
    	}
    	
    	bool operator>(const MyString & st1, const MyString & st2)
    	{
    		return st1 < st2;
    	}
    	
    	bool operator==(const MyString & st1, const MyString & st2)
    	{
    		return (std::strcmp(st1.str, st2.str) == 0);;
    	}
    	
    	ostream & operator<<(ostream & os, const MyString & st)
    	{
    		os << st.str;
    		return os;
    	}
    	
    	istream & operator >> (istream & is, MyString & st)
    	{
    		char temp[MyString::CINLIM];
    		is.get(temp, MyString::CINLIM);
    		if (is)
    			st = temp;
    		while (is && is.get() != '\n')
    			continue;
    		return is;
    	}
    
    
下面的是笔者的微信公众号,欢迎关注,会持续更新c++、python、tensorflow、机器学习、深度学习等系列文章

                      在这里插入图片描述

发布了38 篇原创文章 · 获赞 49 · 访问量 6943

猜你喜欢

转载自blog.csdn.net/Xiao_Jie123/article/details/104200192