Overloaded Functions 前言 處理多載函式宣告的規則 處理多載函式呼叫的規則 多載函式與 scope 函式呼叫的議決.

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

C语言程序设计 主讲教师 :张群燕 电话:
教学目的:了解基础性、公益性投资项目的概念、特点,掌握基础性、公益性投资项目的经济评价方法。
第一章 C语言概述 计算机公共教学部.
C++程序设计 王希 图书馆三楼办公室.
C語言中可變参數的用法——va_list、va_start、va_arg、va_end参數定義
Chapter 5 遞迴 資料結構導論 - C語言實作.
Function Templates 前言 定義函式樣板 函式樣板的實例化 Template Argument Deduction
簡易C++除錯技巧 長庚大學機械系
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
第3章 變數、資料型別與運算子.
2 C++ 程式概論 2.1 C++ 程式結構 程式註解 // 插入標題檔 #include 2-3
列舉(enum).
编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.
Scope & Lifetime 前言 Local Scope Global Functions & Objects
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
101北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C語言簡介 日期 : 2018/12/2.
Object-Oriented Programming in C++ 第一章 C++的初步知识
Class(二) Overloaded Operators User-Defined Conversions 前言 超載運算子
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
第3章 變數、常數與資料型態 3-1 C語言的識別字 3-2 變數的宣告與初值 3-3 指定敘述 3-4 C語言的資料型態
第6章 基本的IDL到C++的映射 3.2 简介 从IDL到C++的映射必须具备下面的条件 (1) 映射应该很直观,并且很容易使用
Methods 靜宜大學資工系 蔡奇偉副教授 ©2011.
第3章 變數、資料型別與運算子 3-1 變數與資料型別的基礎 3-2 變數的命名與宣告 3-3 資料型別 3-4 運算式與運算子
Java 程式設計 講師:FrankLin.
C++语言程序设计 第二章 C++简单程序设计.
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
明解C++教學手冊 柴田望洋 博士 著 書號:PG20269
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
|12 結構與列舉型態.
C#程序设计基础 第二章 数据类型.
第一單元 建立java 程式.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第三章 資料型態與輸出控制 本章學習目標 認識Matlab的基本資料型態 練習資料型態的轉換 學習如何控制Matlab的輸出格式
開始使用Visual C++.
|07 函數.
JAVA 程式設計 資訊管理系 - 網路組.
Java變數 2014/6/24.
數字定位棋 1-7
保留字與識別字.
Class & Object 靜宜大學資工系 蔡奇偉副教授 ©2011.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
C qsort.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 类型、对象、运算符和表达式.
MiRanda Java Interface v1.0的使用方法
第二章 基本数据类型 ——数据的表示.
Review 1~3.
12 虛擬函數 12.1 多載與超載 12-2 多載函數 12-2 超載函數 虛擬函數 12-6 同名異式 12-7
#include <iostream.h>
北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
本节内容 指针类型.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
1757: Secret Chamber at Mount Rushmore
1.4WIN32中的宽字符.
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
第2章 Java语言基础.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
變數與資料型態  綠園.
Array(陣列) Anny
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
方法(Method) 函數.
InputStreamReader Console Scanner
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

Overloaded Functions 前言 處理多載函式宣告的規則 處理多載函式呼叫的規則 多載函式與 scope 函式呼叫的議決

前言 C 語言規定:函式的名稱不可相同。這樣的規定使得我們必須為功能相近但參數型態相異的函式取不同的名稱,譬如: int imax (int, int); // max function for integer double dmax (double , double ); // max function for double 這種命名方式顯然無益於程式的可讀性。C++ 因而解除這個限制,讓函式的名稱可以重複使用,譬如: int max (int, int); // max function for integers double max (double , double ); // max function for integers 這種同名的函式稱之為多載函式(overloaded function)。

程式原始檔中的同名函式可能造成以下四種狀況: 成為合法的多載函式。 成為函式的再次宣告。 產生編譯上的錯誤。 內層的函式宣告隱蓋了外層的同名函式宣告。

處理多載函式宣告的規則 在同一個 scope 中,C++ 編譯器會採用以下的規則來處理同名函式的宣告: 若參數的型態或個數不同的話,則這些同名函式被視為多載函式。譬如: // overloaded functions void print (); void print (int); void print (double);

若傳回值型態以及參數型態和個數都相同的話,則宣告在後的函式被視為再次宣告(redeclaration)。譬如: void print (const string &str); void print (const string &); 若參數型態和個數都相符但傳回值型態不同的話,則宣告在後的函式會產生編譯錯誤。譬如: void print (const string &str); int print (const string &); // compile error

若只是引數預設值不相同的話,則宣告在後的函式被視為再次的宣告。譬如: int max (int *ia, int sz); int max (int *ia, int sz = 10); // redeclaration 由於 typedef 只是提供某種資料型態的別名,而非真正引介新的資料型態,所以資料型態的別名和所指涉的資料型態會被視為相同的型態。譬如:底下的第二個宣告會造成編譯錯誤: typedef double real; real calc (real); int calc (double); // compile error

若修飾字 const 不影響參數的唯讀性,則不被用來區別參數的型態。譬如以下兩行被視為宣告相同的函式: void foo (int); void foo (const int); // redeclaration 若修飾字 const 用於指標或參照,則會被用來區別參數的型態,而形成多載函式。譬如: // 宣告兩個不同的函式 void foo (int *); void foo (const int*); void foo (int &); void foo (const int&);

多載函式與 scope 在相同 scope 的同名函式才會成為多載函式。內層的函式宣告只是隱蓋外層的同名函式宣告,而不是後者的多載函式。譬如: void print (const char *); void print (double); // overloads print() void fooBar (int iVal) { // hide global print() extern void print (int); print("Value: "); // error: print(const char*) is hidden print(iVal); // ok }

開放名稱空間時,同名函式必須符合前述的多載化規定才會形成多載函式,否則會造成編譯的錯誤。我們用以下的幾個例子來說明之。假定名稱空間 IBM 的宣告如下: namespace IBM { void print (int); void print (double); } 以下兩行是正確的: void print (const char *); // 多載函式 using IBM::print; 但以下兩行會造成編譯錯誤: void print (int); using IBM::print; // error: ::print(int) 和 IBM::print(int) 造成混淆。

因為 IBM::print(int) 和 MS::print(int) 造成混淆。 假定名稱空間 IBM 和 MS 的宣告如下: namespace IBM { void print (int); void print (double); } namespace MS { void print (const char*); 則以下兩行會造成編譯錯誤: using namespace IBM; using namespace MS; 因為 IBM::print(int) 和 MS::print(int) 造成混淆。

函式呼叫的議決 由於 C++ 允許多載函式的存在,因此 C++ 編譯器處理函式呼叫時,必須用一套規則來判斷呼叫那一個函式,這個過程稱之為「函式呼叫的議決(resolution)」。舉例來說,假定底下兩個多載函式: void foo (int, int); void foo (double, double); 下列的函式呼叫是呼叫那一個 foo 呢? foo (1, 2); foo (1.0, 2.0); foo (1, 2.0); foo (1, "Hello"); foo ('a', 'b');

C++ 編譯器選擇呼叫的函式時,會根據引數列的型態來找尋與其最相符(best match)的函式。引數列和參數列型態相符比對的優先順序如下: 引數與參數的型態完全一致或經過簡單轉換而一致(如陣列名稱轉成指標、函式名稱轉成函式指標、或型態 T 轉成 const T)。 引數經過型態提昇而與參數相符,如 char → int, float → double 等等。 引數經過標準型態轉換而與參數相符,如 double → int, int → double , int → unsigned int 等等。 引數經過使用者自定的型態轉換而與參數相符。 引數與不定參數列(…)相符。

經過引數列和參數列的型態相符比對後,下列兩種函式呼叫的狀況會產生編譯錯誤: 函式呼叫時的引數無法用前述五項的方式轉換成參數。 範例: void foo (int, int); void foo (double, double); foo (1, 2); // ok: 呼叫 foo(int, int) foo (1.0, 2.0); // ok: 呼叫 foo(double, double) foo (1, 2.0); // error: 無法判斷呼叫那一個 foo (1, “Hello”); // error: 無法轉換 foo ('a', 'b'); // ok: 呼叫 foo(int, int) 函式呼叫時的引數有兩種同等級轉換成參數的方式。

範例:完全相符 void print (int); void print (char); void print (const char*); void print (long); void print (double); char ca[100]; print (3); // match print(int) print (3L); // match print(long) print (3.0); // match print(double) print ('A'); // match print(char) print ("Hello"); // match print(const char*) print (ca); // match print(const char*)

引數提昇轉換的規則 整數的提昇規則 浮點數的提昇規則 引數型態 bool, char, unsigned char, short 提昇成 int。 若 int 的容量大於 short 的容量,則引數型態 unsigned short 提昇成 int,否則提昇成 unsigned int。 列舉型態依其最大值的範圍而提昇成 int, unsigned int, long, 或 unsigned long。 浮點數的提昇規則 引數型態 float 提昇成 double。

範例:經過提昇而相符 void print (int); void print (long); void print (double); enum color {BLACK, WHITE}; print (true); // match print(int), bool → int print (3.0f); // match print(double), float → double print ('A'); // match print(int), char → int print (BLACK); // match print(int), color → int

引數標準轉換的規則 除了前述的整數提昇以外,其他把整數(或列舉)轉換成另一種整數型態,如 int → char。 除了前述的浮點數提昇以外,其他把浮點數轉換成另一種浮點數型態,如 double → float。 整數與浮點數之間的轉換,如 int → double 或 double → int。 指標轉換:如把整數 0 轉成指標;把任何型態的指標轉成 void * 型態的指標。 把任何整數、浮點數、列舉值、指標轉成 bool 型態。

範例:經過標準轉換而相符 void print (char); void print (void *); int *cp; print (3.0); // match print(char), double → char print (3); // match print(char), int → char print (cp); // match print(void *), int * → void *

標準轉換規則是一視同仁而沒有優先次序,比如說: int → double 和 char → double 兩者地位相同。 範例: void print (long); void print (float); void print (void *); void print (bool); int *cp; print (3.14); // error: double → float or double → long? print ('A'); // error: char → float or char → long? print (cp); // error: int * → void * or int * → bool?

多引數的呼叫 呼叫多引數的函式時,前述的型態比對不受引數的順序影響。譬如: 則底下的函式呼叫會造成編譯錯誤: void foo (int, int); void foo (double, double); 則底下的函式呼叫會造成編譯錯誤: foo (1, 2.0); // error: 無法判斷呼叫那一個 因為它可以是 foo (1, int(2.0)) 外,也可以是 foo (double(1), 2.0) ,因此造成混淆。

使用強制的型態轉換 當不明確或會造成混淆時,我們可以用強制的型態轉換(type casting)來呼叫指定的函式。譬如: void print (long); void print (float); void print (void *); void print (bool); int *cp; print (static_cast<float> 3.14); // match print(float) print (static_cast<long>'A'); // match print(long) print (static_cast<void *>cp); // match print(void *)