C++ primer第六章6.4函數的學習 之函數的重載

6.4 函數的重載

  • 函數的名字相同但是形參的列表不同,將其稱之為重載函數
void print(const char *cp);
void print(const int *beg,const int * end);
void print(const int ia[],size_t size);
  • 形如上面所展現的這樣,當調用這些函數的時候,編譯器會根據傳遞的實參類型推斷出想要的是哪個函數。
  • 重載函數在一定程度上減輕了程序員對于起名字和記名字的負擔。
  • mian函數不可以重載

定義承載函數

  • 比如數據庫的應用場景中,定義一個查詢的函數,對于手機號、名字、賬戶號碼分別進行查詢。他們雖然查詢的東西不一樣,但是函數的名字是一樣的,編譯器會根據傳入的實參的類型決定調用哪一個函數。
  • 對于重載函數而言,應該在形參的數量、類型有所不同。
  • 不允許兩個函數除了返回的類型不同,形參列表都相同。那么第二個聲明是錯誤的。

判斷兩個形參的類型是否不同

  • 有時候兩個形參列表看起來不一樣,但是實際上是相同的
//每隊聲明的是同一個函數
record lookup(const Account &acct);
record lookup(const Account &);    //省略了形參的名字
typedef Phone Telno;
record lookup(const Phone&);
record lookup(const Telno&);    //Phone Telno類型一樣

重載和const形參

  • 頂層const不影響傳入函數的對象。一個擁有頂層const的形參無法和一個沒有頂層const的形參區分開來。
record lookup(Phone);
record lookup(const Phone);//重復聲明
record lookup(Phone*);
record lookup(Phone* const);//重復聲明
  • 如果形參是某種類型的指針或者引用,則通過區分其指向的是常量對象還是非常量對象實現函數的重載,這個時候const是底層
//對于接受引用或者指針的函數而言,對象是常量還是非常量對應的形參不同
//定義了四個獨立的重載函數
record lookup(Account&);//函數作用于Account的引用
record lookup(const Account&);//新函數,作用于常量的引用
record lookup(Account*);//新函數,函數作用于Account的指針
record lookup(const Account*);//新函數,作用于指向常量的指針
  • 編譯器可以通過實參是否是常量來推斷調用哪個函數。因為const不可以轉化成其他的類型,所以只可以將const對象(指向const的指針)傳遞給const的形參。
  • 非常量可以轉化成const,所以上面的四個函數都能作用于非常量對象或者指向非常量對象的指針。當傳遞一個非常量對象或者非常量對象的指針的時候,編譯器會優先選用非常量版本的函數。

建議:何時不應該使用重載函數

  • 最好用于指向那些確實非常相似的操作

const_cast和重載

  • 先前
//跳出兩個string對象中較短的那個,并且返回其引用
const string &shorterString(const string &s1,const string &s2){return s1.size() < s2.size() ? s1 : s2;
}
  • 引入一個新的函數,相較于先前的函數,當他的實參不是常量的時候,得到的結果是一個普通的引用,使用const_cast就可以實現這一點。
  • 改進
string &shorterString(string &s1,string &s2){auto &r = shorterString(const_cast<const string&>(s1),const_cast<string&>(s2));return const_cast<string&>(r);
}int main(){string s1 = "Hello";string s2 = "Hello World";cout << shorterString(s1,s2) << endl;}
  • 改進是在先前的基礎上進行封裝了一層,里面還是調用了先前的版本。
  • 改進的版本,首先是將他的實參強制類型轉化成對于const的引用,然后調用了先前的版本,由先前的版本返回對于const string的引用,這個引用事實上綁定在某個函數初始的非常量的實參上。因此,可以再次將其轉化成一個普通的string&,這個過程顯然是安全的。

調用重載的函數

  • 在對于重載的函數進行使用的過程需要一個函數匹配的的過程,這個過程是把函數的調用和一組重載函數中的某一個關聯起來,函數的重載也叫重載確定。
  • 編譯器會根據調用的實參與重載集合中的每一個函數的形參進行匹配,然后根據比較的結果決定到底使用哪個函數
  • 但是有些情形,對于重載函數的比較會很難,比如,當兩個重載函數參數的數量相同和參數的類型可以相互轉化的時候。

匹配的結果

  • 1,編譯器找到一個與實參最佳匹配的函數,并生成調用這個函數的代碼。
  • 2,找不到一個函數和調用的實參相互匹配,此時編譯器會提示無匹配的錯誤
  • 3,對于一個函數可以匹配,但是每一個都不是最佳的選擇,這個時候也是錯誤,稱為二義性調用。

6.4.1 重載和作用域

  • 重載對于函數的作用域并沒有什么特別的改變,如果在內層作用域中聲明名字,它將隱藏外層作用域中聲明的同名的實體。在不同的作用域中無法重載函數的名字。
  • 原則:將函數的聲明置于局部的作用域之內不是一個明智的決定,這里僅僅為了舉例子
void print(const string &);
void print(double );//重載print函數
void fooBar(int ival){
//    bool read = false; //新的作用域:隱藏外層的read,如果把這一行注釋掉,那么string s = read();就不會出錯string s = read(); //如果上面一行存在,會出錯,因為read是一個布爾值,而不是函數cout << s << endl;
}
int main(){fooBar(1);
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447045.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447045.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++有限狀態機的實現

//待完善 有限狀態機是一個很常用的技術&#xff0c;在流程控制和游戲AI中都比較實用&#xff0c;因為狀態機編程簡單又很符合直覺。與有限狀態機類似的是設計模式中的狀態模式。本文是參考《Programming Game AI by Example》 一、 記得最開始工作時候也接觸過有限狀態機&…

手勢希爾排序

void shell_sort(int *data, int length){int gap0;int i0,j0;for(gaplength/2;gap>1;gap/2){//組內插入排序for(igap;i<length;i){int temp data[i];for(ji-gap;j>0&&temp<data[j];jj-gap){data[jgap]data[j];}data[jgap]temp;}} }

Android之android.os.Build

一、類概述&#xff1a;從系統屬性中提取設備硬件和版本信息。 二、內部類&#xff1a; 1、Build.VERSION 各種版本字符串 2、Build.VERSION_CODES 目前已知的版本代碼的枚舉類 三、常量&#xff1a;UNKNOWN 當一個版本屬性不知道時所設定的值。其字符串值為 “unknown” 。 …

C++ unsigned char*轉化為string的形式

unsigned char*轉化為string int main(int argc,char **argv){//unsigned char * 轉化為string//參考鏈接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…

KMP算法面試題

面試題&#xff1a;寫一個在一個宇符串(n)中尋找一個子串&#xff08;m)第一個位置的函數。 10G的日志中&#xff0c;如何快速地查找關鍵字&#xff1f;

C++對于程序調試很有用的系統自帶的名字

簡單介紹 __func__當前調試的函數的名字__FILE__存放文件名的字符串的字面值__LINE__存放當前行號的整型字面值__TIME__存放文件編譯時間的字符串的字面值__DATE__存放文件編譯日期的字符串的字面值 例子 if(word.size() < threshold){cerr << "Error: " …

Android中List、Set、Map數據結構詳解

Android中一般使用的數據結構有java中的基礎數據結構List&#xff0c;Set&#xff0c;Map。還有一些Android中特有的幾個&#xff0c;SparseArray(使用Map時Key是int類型的時候可以用這個代替)等。 繼承關系&#xff1a; Collection<–List<–ArrayList Collection<…

Android設計模式之——單例模式

一、介紹 單例模式是應用最廣的模式之一&#xff0c;也可能是很多初級工程師唯一會使用的設計模式。在應用這個模式時&#xff0c;單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個全局對象&#xff0c;這樣有利于我們協調系統整體的行為。 二、定義 …

我的職業生涯規劃(軟件工程)

以后筆記先在語雀整理 方便一點https://www.yuque.com/juhao-pqdor/goeie3 整理一下自己的筆記 彌補一下以前沒寫博客的遺憾吧 二十載求學路將盡&#xff0c;行文至此&#xff0c;思緒萬千。求學之路始于家鄉&#xff0c;竿轉熱河&#xff0c;而今終于石門。一路行之如人飲水…

C++ primer第六章6.5函數的學習 之特殊用途的語言特性

6.5.1 默認實參 將反復出現的數值稱為函數的默認實參&#xff0c;調用含有默認實參的時候可以包含該實參也可以不包含比如程序打開頁面會有一個默認的寬高&#xff0c;如果用戶不喜歡也允許用戶自由指定與默認數值不同的數值&#xff0c;具體例子如下圖所示 typedef string::s…

Android設計模式之——Builder模式

一、介紹 Builder模式是一步一步創建一個復雜對象的創建型模式&#xff0c;它允許用戶在不知道內部構建細節的情況下&#xff0c;可以更精細的控制對象的構造流程。該模式是為了將構建復雜對象的過程和它的部件解耦&#xff0c;使得構建過程和部件的表示隔離開來。 因為一個復…

c++后端開發書籍推薦

推薦書籍: 略讀80% 精讀50% C&#xff1a; C Primer Plus C和指針&#xff08;入門書 不只是指針&#xff09; C陷阱與缺陷&#xff08;宏相關&#xff09; C專家編程 C&#xff1a; 有專門的視頻 C primer C程序設計原理與實踐&#xff08;c之父寫的 入門經典&#xff09; Ef…

C++ primer第六章6.6函數匹配

函數的匹配 當重載函數的形參數量相等以及某些形參的類型可以由其他的類型轉化得來的時候&#xff0c;對于函數的匹配就會變得很難 確定候選函數和可行函數 函數匹配的第一步就是選定本次調用對應的重載函數集&#xff0c;集合中的函數稱為候選函數。候選函數具有兩個特征&am…

Android設計模式之——原型模式

一、介紹 原型模式是一個創建型的模式。原型二字表明了該模型應該有一個樣板實例&#xff0c;用戶從這個樣板對象中復制出一個內部屬性一致的對象&#xff0c;這個過程也就是我們俗稱的“克隆”。被復制的實例就是我們所稱的“原型”&#xff0c;這個原型也是可定制的。原型模…

C++ primer第六章6.7函數指針

函數指針 函數指針指向的是函數而不是對象。和其他指針一樣&#xff0c;函數指針指向某種特定的類型。函數的類型由他的返回類型和形參類型共同決定&#xff0c;而與函數的名字無關。 //比較兩個string對象的長度 bool lengthCompare(const string &,const string &);…

Android設計模式之——工廠方法模式

一、介紹 工廠方法模式&#xff08;Factory Pattern&#xff09;&#xff0c;是創建型設計模式之一。工廠方法模式是一種結構簡單的模式&#xff0c;其在我們平時開發中應用很廣泛&#xff0c;也許你并不知道&#xff0c;但是你已經使用了無數次該模式了&#xff0c;如Android…

C++ primer第十八章 18.1小結 異常處理

18.1 異常處理 異常處理機制&#xff0c;允許程序獨立開發的部分能夠在運行的時候出現的問題進行通信并且做出相應的處理&#xff0c;異常的處理使得我們可以將問題的檢測和處理分離開來。程序的一部分負責檢測問題的出現&#xff0c;然后將解決這個問題的任務傳遞給程序的另一…

淺談equals與==

一、前言 示例代碼&#xff1a; public static void main(String[] args) throws IOException {String str1 new String("hello");String str2 new String("hello");String str3 "cde";String str4 "cde";int i1 3;int i2 3;In…

針對C++異常的學習

源碼 頭文件 sdf_exception.h #pragma once#include <exception> #include <string>namespace sdf {namespace common{using sdf_error_code_t uint32_t;class SdfException : std::exception{public:explicit SdfException(sdf_error_code_t errorCode) : erro…

Android設計模式之——抽象工廠模式

一、介紹 抽象工廠模式&#xff08;Abstract Factory Pattern&#xff09;&#xff0c;也是創建型設計模式之一。前一節我們已經了解了工廠方法模式&#xff0c;那么這個抽象工廠又是怎么一回事呢&#xff1f;大家聯想一下現實生活中的工廠肯定都是具體的&#xff0c;也就是說…