c++--運算符重載
1.重載的運算符(1).重載運算符函數(shù)的參數(shù)數(shù)量與該運算符作用的運算對象數(shù)量一樣多。(2).除了重載的函數(shù)調(diào)用運算符operator()之外其他重載運算符不能含有默認實參。(3).對一個重載的運算符其優(yōu)先級和結(jié)合律與對應(yīng)的內(nèi)置運算符保持一致。(4).當一個重載的運算符是成員函數(shù)時this綁定到左側(cè)運算對象。故成員運算符函數(shù)的參數(shù)數(shù)量比運算對象數(shù)量少一個。(5).對一個運算符函數(shù)或者是類的成員或者至少含一個類類型的參數(shù)。2.運算符函數(shù)的調(diào)用形式// 假設(shè)有非成員函數(shù)operator顯式operator(data1, data2);隱式data1data2// 假設(shè)有成員函數(shù)operator顯式data1.operator(data2)隱式data1data23.關(guān)于將運算符函數(shù)定義為成員還是非成員賦值下標[]調(diào)用成員訪問箭頭-必須為成員。4.運算符重載4.1.重載(1).通常輸出運算符的第一個形參是一個非常量ostream對象的引用。a. 為引用是因為ostream對象不能被拷貝。b. 非常量是因為向流寫入內(nèi)容會改變其狀態(tài)。(2).第二個形參一般是一個常量的引用該常量是我們想打印的類類型。a. 是引用是因為可以避免值拷貝。b. 常量是因為打印對象不會改變對象的內(nèi)容。(3). 為與其他輸出運算符一致operator一般返回它的ostream形參。(4). 一個實例#include iostream class A { public: int m_a; int m_b; }; std::ostream operator(std::ostream os, const Aitem) { os item.m_a item.m_b; return os; }4.2.重載(1). 通常輸入運算符的第一個形參是運算符將要讀取的流的引用(2). 第二個形參是將要讀入到的非常量對象的引用。(3). 該運算符通常會返回某個給定流的引用。(4). 一個實例#include iostream class A { public: int m_a; int m_b; }; std::istream operator(std::istream is, A item) { char a; is item.m_a a item.m_b; return is; }執(zhí)行輸入時可能發(fā)生下列錯誤(1). 流含有錯誤類型的數(shù)據(jù)時讀取操作可能失敗。(2). 讀取操作到達文件末尾或遇到輸入流的其它錯誤時也會失敗。4.3.算術(shù)運算符4.3.1.最佳實踐(1). 類定義了一個算術(shù)運算符時一般也要定義一個復合賦值運算符。(2). 一般借用復合賦值運算符來定義算術(shù)運算符。(3). 通常算術(shù)和關(guān)系運算符定義為非成員函數(shù)以允許左側(cè)或右側(cè)的運算對象進行轉(zhuǎn)換。(4). 這些運算符一般不需改變運算對象的狀態(tài)故形參可以是常量的引用。(5). 算術(shù)運算的結(jié)果一般位于局部變量內(nèi)。操作完成一般返回局部變量的副本作為結(jié)果。(6). 復合賦值運算符更適合作為類成員來定義。復合賦值應(yīng)該返回引用類型以便支持鏈式賦值(7). 一個實例#include iostream class A { friend bool operator(const A a1, const A a2); public: A():m_a(0), m_b(0){} A(int i):m_a(i), m_b(i){} void print() { printf(a_%d,b_%d\n, m_a, m_b); } A operator(const A a2) { m_a m_a a2.m_a; m_b m_b a2.m_b; return *this; } private: int m_a; int m_b; }; A operator(const A a1, const A a2) { A sum a1; sum a2; return sum; } bool operator(const A a1, const A a2) { return a1.m_a a2.m_a a1.m_b a2.m_b; } bool operator!(const A lhs, const A rhs) { return !(lhs rhs); } int main() { A a1(10); A a2(10); A a3 a1 a2; a3.print(); return 0; }上述是一個為類型A定義運算符!的實例。我們采用類成員定義復合賦值。下述是一個復合賦值采用非成員的版本。#include iostream class A { friend bool operator(const A a1, const A a2); friend A operator(A a1, const A a2); public: A():m_a(0), m_b(0){} A(int i):m_a(i), m_b(i){} void print() { printf(a_%d,b_%d\n, m_a, m_b); } private: int m_a; int m_b; }; // 返回值是復合賦值作為表達式的結(jié)果 // 參數(shù)1是復合賦值左邊操作數(shù)此操作數(shù)會被復合賦值所影響。 A operator(A a1, const A a2) { a1.m_a a2.m_a; a1.m_b a2.m_b; return a1; } A operator(const A a1, const A a2) { A sum a1; sum a2; return sum; } bool operator(const A a1, const A a2) { return a1.m_a a2.m_a a1.m_b a2.m_b; } bool operator!(const A lhs, const A rhs) { return !(lhs rhs); } int main() { A a1(10); A a2(10); A a3 a1 a2; a3.print(); return 0; }4.4.關(guān)系運算符4.4.1.最佳實踐(1). 通常關(guān)系運算符定義為非成員函數(shù)以允許左側(cè)或右側(cè)的運算對象進行轉(zhuǎn)換。(2). 這些運算符一般不需改變運算對象的狀態(tài)故形參可以是常量的引用。以下是一個關(guān)系運算符重載的例子#include iostream class A { friend bool operator(const A a1, const A a2); public: A():m_a(0),m_b(0){} A(int i):m_a(i),m_b(i){} private: int m_a; int m_b; }; bool operator(const A a1, const A a2) { if(a1.m_a a2.m_a a1.m_b a2.m_b) { return true; } else { return false; } } bool operator!(const A a1, const A a2) { return !(a1 a2); } int main() { A a1(1), a2(2); printf(a1a2?%d\n, a1 a2); return 0; }4.5.賦值運算符(1). 賦值運算符限制性因素有賦值作為表達式存在一個結(jié)果數(shù)值。賦值會修改左邊操作數(shù)狀態(tài)。(2). 最佳實踐a. 賦值一般實現(xiàn)為成員函數(shù)b. 為類型自定義賦值運算符時運算符內(nèi)部必須處理b.1. 基類部分賦值b.2. 類型成員賦值c. 為類型自定義賦值運算符時需要考慮自賦值場景。d. 賦值與拷貝針對包含資源的類涉及淺拷貝深拷貝的概念。又涉及到左值右值移動語義完美轉(zhuǎn)發(fā)的概念。這些后續(xù)統(tǒng)一放在專門一篇講解。(3). 一個實例#include iostream class Norm1 { public: Norm1(char i):m_i(i){} void print() { printf(norm1:%c\n, m_i); } private: char m_i; }; class Norm2 { public: Norm2(char i):m_i(i){} void print() { printf(norm2:%c\n, m_i); } private: char m_i; }; class Base { public: Base(char c b):m_n1(c),m_n2(c){} void print() { printf(base:\n); m_n1.print(); m_n2.print(); } private: Norm1 m_n1; Norm2 m_n2; }; class A : public Base { public: A(char c a):Base(c), m_n1(c1),m_n2(c1){} A operator(const A a) { if(this a) { return *this; } Base::operator(a); m_n1 a.m_n1; m_n2 a.m_n2; return *this; } void print() { Base::print(); m_n1.print(); m_n2.print(); } private: Norm1 m_n1; Norm2 m_n2; }; int main() { A a1(x); A a2(a); a1.print(); a2.print(); a1 a2; printf(after:\n); a1.print(); a2.print(); return 0; }4.6.下標運算符對下標運算符最好定義常量和非常量版本對常量版本返回常量引用。4.6.1. 強制性約束從強制性約束角度要求形參列表只能有一個形參#include iostream class Norm { public: void print() const { printf(Norm_%d\n, m_i); } private: int m_i; }; class A { public: int operator[](Norm n) { printf(test[]\n); return 1; } private: Norm m_arrA[10]; }; int main() { A a; Norm n; int i a[n]; return 0; }上述是一個合法的重載的[]運算符。4.6.2. 最佳實踐(1). 形參最好是std::size_t。(2). 重載運算符最好提供常量版本非常量版本。這樣對類型的常量實例非常量實例均可執(zhí)行[]運算。(3). 返回值應(yīng)該設(shè)計成引用類型。標準庫類型[]運算符也均返回引用類型。#include iostream class Norm { public: void print() const { printf(Norm_%d\n, m_i); } private: int m_i; }; class A { public: Norm operator[](std::size_t i) { printf([]\n); return m_arrA[i]; } const Norm operator[](std::size_t i) const { printf([]const\n); return m_arrA[i]; } private: Norm m_arrA[10]; }; int main() { A a; a[1].print(); const A a1 A(); a1[1].print(); return 0; }上述是一個[]運算符重載的最佳實例4.7.遞增和遞減運算符4.7.1.強制性約束(1).對后置版本的--形參列表必須提供單個類型為int的形參。(2).對前置版本的--形參列表必須為空。#include iostream class A { public: A() : m_i(0) {} int operator() { printf(()\n); m_i; return 1; } int operator(int n) { printf((int)\n); A temp *this; m_i; return 1; } private: int m_i; }; int main() { A a; a; a; return 0; }上述是一個合法的前置后置運算符的重載實現(xiàn)。4.7.2.最佳實踐(1). 定義--運算符時候應(yīng)該同時定義前置版本后置版本。(2). 前置版本應(yīng)該返回類型自身的引用。后置版本應(yīng)該返回類型自身。與標準庫類型保持一致。(3). 不應(yīng)該提供常量版本。#include iostream class Norm { private: int m_i; }; class A { public: A() : m_i(0) {} A operator() { printf(()\n); m_i; return *this; } A operator(int) { printf((int)\n); A temp *this; m_i; return temp; } private: int m_i; }; int main() { A a; a; a; return 0; }上述是一個前置后置的最佳實踐。4.8.成員訪問運算符*-4.8.1. 強制性約束(1).對*運算符必須提供0個形參或1個形參。(2).對-運算符必須提供0個形參。#include iostream class Norm { public: Norm(int i) : m_i(i) {} void print() { printf(i_%d\n, m_i); } private: int m_i; }; class A { public: int operator*(Norm) { printf(*\n); return 1; } int operator-() { printf(-\n); return 2; } private: int m_i; }; int main() { A a; A *p a; Norm n(1); p-operator-(); p-operator*(n); a.operator*(n); a.operator-(); // a-print(); //*a; return 0; }上述我們?yōu)轭愋投x了一個合法的*運算符一個合法的-運算符。4.8.2.最佳實踐(1).*運算符的形參應(yīng)該是0個。因為只有這樣才能使用A a; *a;這樣的方式觸發(fā)*運算符訪問。(2).-運算符的返回類型應(yīng)該要么是重載了-運算符的類型要么是指針類型。因為如下述我們執(zhí)行A a; a-print();這樣的操作時。操作處理細節(jié)為a. 若a重載了-運算符。則執(zhí)行運算符獲得返回值。否則報錯。b. 若返回值是指針類型進入到對指針類型執(zhí)行-情形。終止。c. 若返回值不是指針類型且重載了-運算符則執(zhí)行運算符獲得返回值。否則報錯終止。b. 進入2。我們下述的a-print()對應(yīng)的輸出為#include iostream class Norm { public: Norm(int i) : m_i(i) {} Norm *operator-() { printf(norm -\n); return this; } void print() { printf(i_%d\n, m_i); } private: int m_i; }; class A { public: Norm operator*() { Norm n(1); printf(*\n); return n; } Norm operator-() { Norm n(11); printf(-\n); return n; } private: int m_i; }; int main() { A a; A *p a; p-operator-(); p-operator*(); a.operator*(); a.operator-(); a-print(); *a; return 0; }4.8.3. 注意點以4.8.2中實例為說明對象。整理c類型中成員訪問細節(jié)。int main() { A a; A *p a; p-operator-(); p-operator*(); a.operator*(); a.operator-(); a-print(); *a; return 0; }(1). 針對指針類型基于指針執(zhí)行-可以訪問到指針指向?qū)ο蟮某蓡T。此行為不允許重載。(2). 針對非指針類型稱其為對象類型基于對象類型執(zhí)行.可以訪問到對象的成員。此行為不允許重載。(3). 調(diào)用類型*-運算符的形式有顯式和隱式。a. 顯式調(diào)用諸如int main() { A a; A *p a; p-operator-(); p-operator*(); a.operator*(); a.operator-(); return 0; }b.隱式調(diào)用諸如int main() { A a; a-print(); *a; return 0; }4.9.函數(shù)調(diào)用運算符4.9.1.強制性約束對形參列表無強制性約束。#include iostream class A { public: A() {} int operator()(int) { printf((int)\n); return 0; } int operator()(int, int) { printf((int,int)\n); return 1; } private: int m_i; }; int main() { A a; a(1); a(1, 2); return 0; }上述我們定義了兩個函數(shù)調(diào)用運算符分別接收一個參數(shù)兩個參數(shù)。定義類函數(shù)調(diào)用運算符的類類的對象稱作函數(shù)對象。4.10.轉(zhuǎn)換構(gòu)造函數(shù)4.10.1.強制性約束我們稱只傳遞一個實參即可調(diào)用的構(gòu)造函數(shù)為轉(zhuǎn)換構(gòu)造函數(shù)#include iostream class A { public: A(int i, int j 0) : m_i(i) { printf(A(int)_%d\n, i); } private: int m_i; }; void fun(A a) { } int main() { fun(1); return 0; }上述我們定義了一個轉(zhuǎn)換構(gòu)造函數(shù)。因為有了此轉(zhuǎn)換構(gòu)造函數(shù)上述fun(1)執(zhí)行中先基于1構(gòu)造得到類型A的實例再執(zhí)行函數(shù)調(diào)用。若要阻止這類默認轉(zhuǎn)換只需將轉(zhuǎn)換構(gòu)造用explicit修飾。此時只能通過顯式構(gòu)造基于int得到類型A實例。#include iostream class A { public: explicit A(int i, int j 0) : m_i(i) { printf(A(int)_%d\n, i); } private: int m_i; }; void fun(A a) { } int main() { fun(A(1)); return 0; }4.11.類型轉(zhuǎn)換運算符4.11.1.強制性約束類型轉(zhuǎn)換運算符的形參列表必須為空#include iostream class Norm { public: private: char m_c; }; class A { public: explicit A(int i, int j 0) : m_i(i) { printf(A(int)_%d\n, i); } operator int() { printf(int()\n); return m_i; } operator Norm() { printf(Norm()\n); Norm n; return n; } private: int m_i; }; void fun(A a) { } int main() { fun(A(1)); A a(1); int n 1 a; printf(n_%d\n, n); Norm nn a; return 0; }上述我們定義了兩個類型轉(zhuǎn)換運算符分別轉(zhuǎn)換到intNorm類型。

相關(guān)新聞

Ubuntu 上搭建Samba和nfs服務(wù)

Ubuntu 上搭建Samba和nfs服務(wù)

一、Ubuntu上搭建Samba服務(wù)1.安裝Sambasudo apt-get install samba samba-common2.如果你開啟了防火墻,關(guān)閉sudo systemctl stop ufw3.配置Samba,編輯配置文件sudo vim /etc/samba/smb.conf直接共享家目錄,修改如下:4.添加一個用戶…

2026/8/2 19:17:02 閱讀更多
nginx的安裝與部署

nginx的安裝與部署

nginx的安裝與部署1、下載源碼包2、修改配置文件3、配置開機自啟動3、驗證1、下載源碼包 #下載最新穩(wěn)定版(替換版本號) wget https://nginx.org/download/nginx-1.28.3.tar.gz#解壓 tar -zxvf nginx-1.28.3.tar.gz cd nginx-1.28.3#安裝依賴 #Ubuntu …

2026/8/2 20:17:04 閱讀更多
線段與同級別分解:構(gòu)建市場走勢的標準化分析框架

線段與同級別分解:構(gòu)建市場走勢的標準化分析框架

1. 項目概述:線段與同級別分解的核心邏輯 在技術(shù)分析的實戰(zhàn)中,我們常常會遇到一個難題:市場走勢紛繁復雜,如何從看似無序的波動中,提煉出清晰、客觀、可操作的結(jié)構(gòu)?這正是“線段”與“同級別分解”這兩個概…

2026/8/2 20:17:04 閱讀更多
【單片機課程設(shè)計/畢業(yè)設(shè)計】基于 51/STM32 單片機的醫(yī)護端優(yōu)先級呼叫處理設(shè)備設(shè)計 無線傳輸型 8 床位智能呼叫與定時播報系統(tǒng)開發(fā)(020301)

【單片機課程設(shè)計/畢業(yè)設(shè)計】基于 51/STM32 單片機的醫(yī)護端優(yōu)先級呼叫處理設(shè)備設(shè)計 無線傳輸型 8 床位智能呼叫與定時播報系統(tǒng)開發(fā)(020301)

博主介紹:??碼農(nóng)一枚 ,專注于大學生項目實戰(zhàn)開發(fā)、講解和畢業(yè)🚢文撰寫修改等。全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,博客之星、掘金/華為云/阿里云/InfoQ等平臺優(yōu)質(zhì)作者、專注于嵌入式單片機,Java、小程序技術(shù)領(lǐng)域和畢業(yè)項目實戰(zhàn) ??…

2026/8/2 20:07:03 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說說 項目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發(fā)過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南

3分鐘搞定!QQ空間歷史說說完整備份終極指南 【免費下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說說 項目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過,那些年發(fā)過的QQ空間說說,那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導體設(shè)備的I/O信號分配電路板。該型號(0100-02186)的核心特點如下:專用于Endura等半導體工藝腔室。集成信號路由與分配功能。連接控制…

2026/8/2 2:51:21 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動機是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機,適用于自動化設(shè)備及通用機械驅(qū)動。該型號(FFMN-32L-10-T0 40AX)的核心特點如下:三相交流異步電動機。額定…

2026/8/2 2:52:49 閱讀更多