運算符重載
- 1.運算符重載--重點
- 2.友元函數--難點(流運算符重載)
《老九學堂C++課程》《C++ primer》學習筆記。《老九學堂C++課程》詳情請到B站搜索《老九零基礎學編程C++入門》
-------------簡單的事情重復做,重復的事情用心做,用心的事情堅持做(老九君)---------------
C++創始人:要輕松的使用這種語言,不要覺得必須使用所有的特性,不要在第一次學習的時候就試圖使用所有的特性。
1.運算符重載–重點
1.函數的重載和參數有關,和函數名無關。
2.運算符重載就是“想法的轉換”,它的目標是簡化函數調用的方式。
3.把標準的函數使用方式,重新定義成自己認為的方式。給符號賦予新的含義,使得一個運算符可以擁有不同的功能。
實際上:我們已經用過了很多運算符的重載,C++本身已經對這些運算符進行了重載
- +號可以實現不同類型數據的加法操作。
- << 既是位移運算符,又可以配cout 實現控制臺數據的輸出
兩個對象想要進行相加,必須進行運算符重載。重載的一個效果是為了是為了美觀
小試牛刀:定義一個運算符重載,就像是定義了一個函數,只不過這個函數名稱以關鍵字operator開頭.
運算符重載的語法格式為:
返回類型 operater被重載的運算符(參數列表)
編譯器實際調用:
num3 = num1.operator+(num2);
demo1:重載加法運算符1
//mian.cpp
#include <iostream>
#include "Integer.h"
using namespace std;
void TestInteger();
void TestIntefer()
{Integer int1(1024), int2(2048),int3;int3 = int1 + int2;cout << "int3 = int1 + int2的結果為" << int3.Intvalue()<< endl;
}
int main() {TestIntefer();return 0;
}
//Integer.h
//
// Created by 陳瑩瑩 on 2021/2/14.
// 我們自己定義的整型類,將整型封裝成類,以便面向對象的封裝#ifndef CHAPTER12_INTEGER_H
#define CHAPTER12_INTEGER_Hclass Integer {
public:Integer();Integer(int value):m_value(value){}// 重載加號運算符Integer operator+(Integer other);int Intvalue(){return m_value;}~Integer();
private:int m_value; // 實際的整型數字,提供一些十分方便操作的函數};
//Integer.cpp
//
// Created by 陳瑩瑩 on 2021/2/14.
//#include "Integer.h"
//調用默認構造時會為m_value賦一個默認值為0
Integer::Integer():m_value(0)
{//ctor
}
Integer Integer::operator+(Integer other)
{Integer result(this->m_value + other.m_value); // 加法的結果,返回return result;
}
Integer::~Integer()
{//dtor
}
demo2:重載加法運算符2–()
// 重載加號運算符2--對應的.cpp 需要改變// const Integer &operator+(const Integer & other) const;const Integer operator+(const Integer & other) const;// 第一個const 修飾返回值,返回值用引用更好(報錯,不返回引用)// 第二個const 修飾參數,傳遞的是參數的引用,并且不希望改變參數// 第三個const 不修改當前的成員變量
//Integer.cpp
const Integer Integer::operator+(const Integer & other) const
{Integer result(this->m_value + other.m_value); // 加法的結果,返回return result;
}
可以被重載的運算符包括所有的C的運算符,可以重載的運算符列表如下
二遠運算符 | +,-,*,/,% |
---|---|
關系運算符 | ==, !=, <, >, <=, >= |
邏輯運算符 | |
一元運算符 | +正, -負, *(指針), &(取地址), ++(自增), --(自減) |
位運算符 | &, |
賦值運算符 | =, +=, -=, *=, /=, %=, &=, |
內存聲明與釋放 | new, delete, new[], delete[] |
其他運算符 | ()(函數), ->(成員訪問), ->*(成員指針訪問), ,(逗號), [](下標) |
不能被重載的運算符
. | 點運算符 |
---|---|
* | 成員指針訪問運算符 |
:: | 域運算符 |
sizeof | 長度運算符 |
?: | 三元運算符 |
預算符重載的注意點:
1.重載不能修改運算變量的個數
2.重載不能修改運算符的優先級別
3.重載不能修改運算順序
(運算符重載先聽一遍,之后需要的化買《Effective C++》(更高效的C++)再看)
在條款10:重載賦值運算符(復合賦值符號)的建議用法:返回*this。返回一個新建對象也可以,但是不夠高效。
在條款11: 如果是自我賦值,就不要做任何事情。
2.友元函數–難點(流運算符重載)
Integer num1(1024), Integer num2(24);
Integer num3 = num1 + num2; // 正常執行
Integer num4 = 1024 + num1; // 編譯錯誤。 因為int 類型中沒有重載+ 號
使用友元函數,重載運算符時加一個friend關鍵字。 可以直接訪問類的私有成員。
(僅摘錄相關代碼)
demo: 友元函數重載,+,流運運算符
//main.cppInteger int5;// int5 = int4 + 1024; // 沒有實現友元函數也能夠運行的寫法int5 = 1024 + int4; // 加了友元函數才能過cout << "int5 = " << int5.Intvalue() << endl;// 重載流運算符--可以實現封裝某個對象的打印格式cout << "重載了流運算符,可以直接打印對象" << int5 << endl;Integer int6;cin >> int6;cout << "輸入的int6為:" << int6;
//Integer.h// 友元函數--friendfriend const Integer operator+(int intValue, const Integer & other); // 最后不能加const會報錯// 重載流運算符--一般只能使用友元的方式,返回值插入流,會變所以不用const 修飾返回值friend ostream & operator<<(ostream & out, const Integer & num);friend istream & operator>>(istream & in, Integer & num);
//Integer.cpp
// 友元函數不需要使用域運算符號
const Integer operator+(int intValue, const Integer & other){cout << "使用友元方式重載了+運算符,實現int類型和Integer類型的相加" << endl;return Integer(intValue + other.m_value); // 返回了一個新的Integer對象
}
ostream & operator<<(ostream & out, const Integer & num){out << num.m_value;return out;
}
istream & operator>>(istream & in, Integer & num){cout << "請輸入一個整數:" ;in >> num.m_value;return in;
}
運算符聲明成類成員還是聲明成獨立友元函數的建議準則 | |
---|---|
必須聲明為成員函數 | 賦值預算符=、數組下標預算符[]、函數調用運算符()、成員訪問運算符-> |
必須聲明為友元函數 | 流預算符>>、<<、類型轉換運算符 |
一般聲明為友元函數 | 一元運算符、復合賦值運算符 |
一般聲明為友元函數 | 二元運算符 |
注意:
- 剩下的預算符可以友元也可以成員函數重載
- 必須選擇一種方式,避免二義性,參數列表不同就是不同的兩個重載
- 沒有絕對的好壞,按上表建立來就可以。