就像其他子例程一样,重载子例程也被调用。要确定要调用哪个函数,重要的是确定参数的数量和类型。例如,下面的代码部分将介绍调用重载子例程:
prnsqr('z') // calls #2
prnsqr(13) // calls #1
prnsqr(134.520000012) // calls #4
prnsqr(12.5F) // calls #3
当函数调用最初与可用的原型以及给定的参数的数字和类型匹配时,将调用适当的函数以执行。
在float,double值或int或long值之间,可能存在歧义,例如以下声明所调用的函数:
void prnsqr(double d);
值为1.24,可以假定为float或double。常量后缀(F,U,L,UL)等用于避免歧义,这些值有助于说明要调用哪个重载子例程。普通的浮点常量(312.32)是双精度型,后缀F(312.32 F)是浮点型,L(312.32 L)使其长双精度型。对于整数,不带后缀的常量是有符号的int值。 U后缀为无符号常量,L后缀为long,LU或UL后缀为unsigned long。这些后缀可以用小写或大写字母书写。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
class Distance {
private:
int centimeter;
int kilometer;
public:
// Default Constructors
Distance()
{
centimeter = 0;
kilometer = 0;
}
// Parameterized Constructors
Distance(int cm, int km)
{
centimeter = cm;
kilometer = km;
}
// Overload function call
Distance operator()(int a,
int b, int c)
{
Distance D;
D.centimeter = a + c + 10;
D.kilometer = b + c + 100;
return D;
}
// To display distance
void displayDistance()
{
cout << "centimeter: "
<< centimeter
<< "kilometer:"
<< kilometer << '\n';
}
};
// Driver Code
int main()
{
Distance D1(87, 33), D2;
cout << "First Distance : ";
D1.displayDistance();
// Invoke operator()
D2 = D1(10, 10, 10);
cout << "Second Distance :";
D2.displayDistance();
return 0;
}
C++
// C++ program for the above approach
#include
using namespace std;
// Function for integer parameter
void afunc(int h)
{
cout << "Integer:" << h;
}
// Function for double parameter
void afunc(double d)
{
cout << "double:" << d;
}
// Driver code
int main()
{
afunc(0);
return 0;
}
C++
// C++ program for the above approach
#include
using namespace std;
// Function for integer parameter
void value(int s)
{
cout << "Integer:" << s;
}
// Function for character parameter
void value(char* b)
{
cout << "Char:" << b;
}
// Driver Code
int main()
{
char st = 'd';
value(st);
return 0;
}
C++
// C++ program to explain the standard
// conversion rule
#include
using namespace std;
// Driver Code
int main()
{
// integer h
int h = 11;
// character c
char s = 'a';
// s implicitly converted
// to int. ASCII value of
// 'a' is 97
h = h + s;
// h is implicitly converted
// to float
float f = h + 1.0;
cout << "h = " << h << endl
<< "s = " << s << endl
<< "f = " << f << endl;
return 0;
}
C++
// C++ program to illustrate the user
// defined type casting
#include
using namespace std;
// Driver Code
int main()
{
double h = 1.4;
// Explicit conversion
// from double to int
int add = (int)h + 2;
cout << "Add = " << add;
return 0;
}
First Distance : centimeter: 87kilometer:33
Second Distance :centimeter: 30kilometer:120
找到准确匹配的方法:
通过一个实例实例,通过称为参数匹配的过程(也称为歧义消除过程),通过一个函数实例来解决该重载子例程的调用。以下是3种可能的情况,可能会导致函数调用:
- 匹配:发现用于函数调用。
- 不匹配:用于函数调用。
- 模糊匹配:不只一个描述的实例匹配。
编译器将尝试为函数调用找到最佳匹配。
编译器进行匹配的步骤
- 搜索完全匹配:当实际参数类型与一个已定义实例的类型完全匹配时,编译器将为该实例调用。举些例子:
// For overloaded functions void afunc(int); void afunc(double); // For exact match. Match afunc(int) afunc(0);
0(零)是int类型,将afunc(int)与call匹配。
以下是相同的程序:
C++
// C++ program for the above approach #include
using namespace std; // Function for integer parameter void afunc(int h) { cout << "Integer:" << h; } // Function for double parameter void afunc(double d) { cout << "double:" << d; } // Driver code int main() { afunc(0); return 0; } 输出:Integer:0
- 通过提升匹配:如果未找到完全匹配,则编译器将尝试通过提升实际参数来获取匹配。如果所有值都不能用int表示,并且将整数类型转换为(char,short,enumerator,int)或无符号int,则称为整数提升。现在,我们将看到以下代码部分:
void afunc(int)
void afunc(float)// For match through promotion
afunc(‘c’)where, ‘c’ is the type char and promoted to INT type as no exact match found.
以下是相同的程序:
C++
// C++ program for the above approach #include
using namespace std; // Function for integer parameter void value(int s) { cout << "Integer:" << s; } // Function for character parameter void value(char* b) { cout << "Char:" << b; } // Driver Code int main() { char st = 'd'; value(st); return 0; } 输出:Integer:100
- 通过应用标准C++转换规则,找到了一个匹配项:如果未找到完全匹配项或通过提升找到匹配项,则尝试通过实际参数的标准转换来实现匹配项。下面是相同的示例:
void afunc(char)
void afunc(double)// For match through std conversion
afunc(471)
match a func(double)使用C++标准转换规则,可以将int参数471转换为双精度值471,并且如果实际参数可以转换为多种形式参数类型,则编译器将生成错误消息,因为它是模棱两可的匹配项。例如:
void afunc(long) void afunc(double) // Error will generate as ambiguous match afunc(15)
将int参数15转换为long或double会产生关于使用afunc()的模棱两可的情况。
以下是相同的程序:
C++
// C++ program to explain the standard // conversion rule #include
using namespace std; // Driver Code int main() { // integer h int h = 11; // character c char s = 'a'; // s implicitly converted // to int. ASCII value of // 'a' is 97 h = h + s; // h is implicitly converted // to float float f = h + 1.0; cout << "h = " << h << endl << "s = " << s << endl << "f = " << f << endl; return 0; } 输出:h = 108 s = a f = 109
注意:如果未看到升级,则编译器将通过标准转换找到匹配项。任何数字类型都与另一个数字类型(包括无符号)(例如int和float)匹配。枚举将与数字类型的形式类型匹配(例如,浮点枚举)。 0必须与指针类型和数字类型相匹配(例如,将0表示为char *,将0表示为浮点数)。虽然Pointer与void指针匹配。
- 通过应用用户定义转换来找到匹配项:如果上述所有步骤均失败,则编译器将结合使用用户定义的转换,积分提升和内置转换来查找唯一的匹配项。在给定的C++中,任何函数(无论是类成员还是普通函数)都可以在C++中重载,以适用于不同的参数类型数字和组合。
以下是相同的程序:
C++
// C++ program to illustrate the user // defined type casting #include
using namespace std; // Driver Code int main() { double h = 1.4; // Explicit conversion // from double to int int add = (int)h + 2; cout << "Add = " << add; return 0; } 输出:Add = 3