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;
    	}
    
    
發佈了22 篇原創文章 · 獲贊 13 · 訪問量 4855
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章