打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
第一部分 基础语言之六函数
6.1 函数的定义
6.1.1  函数返回类型 
函数的返回类型可以是内置类型(如 int 或者 double)、类类型或复合类型(如int& 或 string*),还可以是 void 类型,表示该函数不返回任何值。函数不能返回另一个函数或者内置数组类型(因为数组不能复制或赋值),但可以返回指向函数的指针,或指向数组元素的指针的指针(数组的指针可以复制或赋值)
 // ok: pointer to first element of the array 
int *foo_bar() { /* ... */ }
 这个函数返回一个 int 型指针,该指针可以指向数组中的一个元素。
函数必须指定返回类型 
在定义或声明函数时,没有显式指定返回类型是不合法的:
 // error: missing return type
test(double v1, double v2) { /* ... */ }   
早期的 C++ 版本可以接受这样的程序,将 test 函数的返回类型隐式地定义为int 型。但在标准 C++ 中,上述程序则是错误的。在 C++ 标准化之前,如果缺少显式返回类型,函数的返回值将被假定为 int 型。早期未标准化的 C++ 编译器所编译的程序可能依然含有隐式返回 int 型的函数。

6.1.2. 函数形参表 
函数形参表可以为空,但不能省略。没有任何形参的函数可以用空形参表或含有单个关键字 void 的形参表来表示。例如,下面关于 process 的声明是等价的: 
void process() { /* ... */ } // implicit void parameter list 
void process(void){ /* ... */ } // equivalent declaration 
形参表由一系列用逗号分隔的参数类型和(可选的)参数名组成。如果两个参数具有相同的类型,则其类型必须重复声明:
int manip(int v1, v2) { /* ... */ } // error 
int manip(int v1, int v2) { /* ... */ } // ok

6.2 参数传递
6.2.1. 非引用形参
普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。
指针形参
函数的形参可以是指针,此时将复制实参指针。与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。如果函数将新指针赋给形参,主调函数使用的实参指针的值没有改变。
如果保护指针指向的值,则形参需定义为指向 const 对象的指针:
void use_ptr(const int *p)
{
// use_ptr may read but not write to *p
}
指针形参是指向 const 类型还是非 const 类型,将影响函数调用所使用的实参。我们既可以用    int* 也可以用 const int* 类型的实参调用 use_ptr 函数;可以将指向 const 对象的指针初始化为指向非 const对象,但不可以让指向非 const 对象的指针向 const 对象。
const形参
如果该函数使用非引用的非 const 形参,则既可给该函数传递 const 实参也可传递非 const 的实参。这种行为源于 const 对象的标准初始化规则。因为初始化复制了初始化式的值,所以可用 const 对象初始化非 const 对象,反之亦然。
如果将形参定义为非引用的 const 类型:
void fcn(const int i) { /* fcn can read but not write to i */ }
则在函数中,不可以改变实参的局部副本。由于实参仍然是以副本的形式传递,因此传递给       fcn 的既可以是 const 对象也可以是非 const 对象。令人吃惊的是,尽管函数的形参是 const,但是编译器却将 fcn 的定义视为其形码被声明为普通的 int 型:
void fcn(const int i) { /* fcn can read but not write to i */ }
void fcn(int i) { /* ... */ } // error: redefines fcn(int)
这种用法是为了支持对 C 语言的兼容,因为在 C 语言中,具有 const 形参或非 const 形参的函数并无区别。

复制实参的局限性
复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:
· 当需要在函数中修改实参的值时。
· 当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出的时间和存储空间代    价往往过在。
· 当没有办法实现对象的复制时。

6.2.2  引用形参
从 C 语言背景转到 C++ 的程序员习惯通过传递指针来实现对实参的访问。在 C++ 中,使用引用形参则更安全和更自然。

使用引用形参返回额外的信息
了解了如何利用引用形参让函数修改实参的值。引用形参的另一种用法是向主调函数返回额外的结果。

利用const 引用避免复制
在向函数传递大型对象时,需要使用引用形参,这是引用形参适用的另一种情况。虽然复制实参对于内置数据类型的对象或者规模较小的类类型对象来说没有什么问题,但是对于大部分的类类型或者大型数组,它的效率(通常)太低了;某些类类型是无法复制的。使用引用形参,函数可以直接访问实参对象,而无须复制它。
// compare the length of two strings
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
其每一个形参都是 const string 类型的引用。因为形参是引用,所以不复制实参。又因为形参是 const 引用,所以 isShorter 函数不能使用该引用来修改实参。
如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为 const 引用。

更灵活的指向 const 的引用
如果函数具有普通的非 const 引用形参,则显然不能通过 const 对象进行调用。毕竟,此时函数可以修改传递进来的对象,这样就违背了实参的 const 特性。
// function takes a non-const reference parameter
int incr(int &val)
{
return ++val;
}
int main()
{
short v1 = 0;
const int v2 = 42;
int v3 = incr(v1);  // error: v1 is not an int
v3 = incr(v2); // error: v2 is const
v3 = incr(0); // error: literals are not lvalues
v3 = incr(v1 + v2);   // error: addition doesn't yield an lvalue
int v4 = incr(v3);      // ok: v3 is a non const object type int
}
应该将不需要修改的引用形参定义为 const 引用。普通的非 const 引用形参在使用时不太活。这样的形参既不能用 const 对象初始化,也不能用字面值或产生右值的表达式实参初始化。

传递指向指针的引用
假设我们想编写一个与前面交换两个整数的 swap 类似的函数,实现两个指针的交换。已知需用 * 定义指针,用 & 定义引用。现在,问题在于如何将这两个操作符结合起来以获得指向指针的引用。这里给出一个例子:
 // swap values of two pointers to int 
void ptrswap(int *&v1, int *&v2)
 {
  int *tmp = v2;
  v2 = v1;
  v1 = tmp;
 }
定义应从右至左理解:v1 是一个引用,与指向 int 型对象的指针相关联。也就是说,v1 只是传递进 ptrswap 函数的任意指针的别名,它将交换两个实参指针指向的对象。

6.2.3  vector和其他容器类型的形参
通常,函数不应该有 vector 或其他标准库容器类型的形参。调用含有普通的非引用 vector 形参的函数将会复制 vector 的每一个元素。

6.2.4. 数组形参
数组有两个特殊的性质,影响我们定义和使用作用在数组上的函数:一是不能复制数组;二是使用数组名字时,数组名会自动转化为指向其第一个元素的指针。因为数组不能复制,所以无法编写使用数组类型形参的函数。因为数组会被自动转化为指针,所以处理数组的函数通常通过操纵指向数组指向数组中的元素的指针来处理数组。
数组形参的定义
如果要编写一个函数,输出 int 型数组的内容,可用下面三种方式指定数组形参:
// three equivalent definitions of printValues
void printValues(int*) { /* ... */ }
void printValues(int[]) { /* ... */ }
void printValues(int[10]) { /* ... */ }
虽然不能直接传递数组,但是函数的形参可以写成数组的形式。虽然形参表示方式不同,但可将使用数组语法定义的形参看作指向数组元素类型的指针。上面的三种定义是等价的,形参类型都是 int*。
通常,将数组形参直接定义为指针要比使用数组语法定义更好。这样就明确地表示,函数操纵的是指向数组元素的指针,而不是数组本身。由于忽略了数组长度,形参定义中如果包含了数组长度则特别容易引起误解。
编译器忽略为任何数组形参指定的长度!!!
数组实参
和其他类型一样,数组形参可定义为引用或非引用类型。大部分情况下,数组以普通的非引用类型传递,此时数组会悄悄地转换为指针。一般来说,非引用类型的形参会初始化为其应实参的副本。而在传递数组时,实参是指向数组第一个元素的指针,形参复制的是这个指针的值,而不是数组元素本身。函数操纵的是指针的副本,因此不会修改实参指针的值。然而,函数可通过该指针改变它所指向的数组元素的值。通过指针形参做的任何改变都在修改数组元素本身。不需要修改数组形参的元素时,函数应该将形参定义为指向 const 对象的指针.
通过引用传递数组
和其他类型一样,数组形参可声明为数组的引用。如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身。在这种情况下,数组大小成为形参和实参类型的一部分。编译器检查数组的实参的大小与形参的大小是否匹配:
// ok: parameter is a reference to an array; size of array is fixed
void printValues(int (&arr)[10]) { /* ... */ }
int main()
{
int i = 0, j[2] = {0, 1};
int k[10] = {0,1,2,3,4,5,6,7,8,9};
printValues(&i); // error: argument is not an array of 10 ints
printValues(j); // error: argument is not an array of 10 ints
printValues(k); // ok: argument is an array of 10 ints
return 0;
}

多维数组的传递
// first parameter is an array whose elements are arrays of 10 ints
void printValues(int (*matrix)[10], int rowSize);
和其他数组一样,多维数组以指向 0 号元素的指针方式传递。多维数组的元素本身就是数组。除了第一维以外的所有维的长度都是元素类型的一部分,必须明确指定:
// first parameter is an array whose elements are arrays of 10 ints
void printValues(int (*matrix)[10], int rowSize);
上面的语句将 matrix 声明为指向含有 10 个 int 型元素的数组的指针。我们也可以用数组语法定义多维数组。与一维数组一样,编译器忽略第一维的长度,所以最好不要把它包括在形参表内:
// first parameter is an array whose elements are arrays of 10 ints
void printValues(int matrix[][10], int rowSize);
这条语句把 matrix 声明为二维数组的形式。实际上,形参是一个指针,指向数组的数组中的元素。数组中的每个元素本身就是含有 10 个 int 型对象的数组。

6.2.5 main: 处理命令行选项
主函数 main 是演示 C 程序如何将数组传递给函数的好例子。直到现在,我们所定义的主函数都只有空的形参表:
int main() { ... }
这种用法的处理方法实际上是在主函数 main 中定义了两个形参:
int main(int argc, char *argv[]) { ... }
第二个形参 argv 是一个 C 风格字符串数组。第一个形参 argc 则用于传递该数组中字符串的个数。由于第二个参数是一个数组,主函数 main 也可以这样定义:
int main(int argc, char **argv) { ... }
表示 argv 是指向 char* 的指针。
6.2.6. 含有可变形参的函数
C++ 中的省略符形参是为了编译使用了 varargs 的 C 语言程序。关于如何使用 varargs,请查阅所用 C 语言编译器的文档。对于 C++ 程序,只能将简单数据类型传递给含有省略符形参的
函数。实际上,当需要传递给省略符形参时,大多数类类型对象都不能正确地复制。
在无法列举出传递给函数的所有实参的类型和数目时,可以使用省略符形参。省略符暂停了类型检查机制。它们的出现告知编译器,当调用函数时,可以有 0 或多个实参,而实参的类型未知。省略符形参有下列两种形式:
void foo(parm_list, ...);
void foo(...);

6.3 return语句
return 语句用于结束当前正在执行的函数,并将控制权返回给调用此函数的函数。return 语句有两种形式:
return;
return expression;
6.3.1 没有返回值的函数
用来控制函数提前退出,这种函数不能使用第二种形式,但是可以返回同样是void函数的调用结果例如:
void do_swap(int &v1, int &v2)
{
int tmp = v2;
v2 = v1;
v1 = tmp;
// ok: void function doesn't need an explicit return
}
void swap(int &v1, int &v2)
{
if (v1 == v2)
return false; // error: void function cannot return a value
return do_swap(v1, v2); // ok: returns call to a void function
}

6.3.2 具有返回值的函数
1.mian函数的返回
必须有返回值return 语句,否则出错,有一个特里就是main函数,mian函数可以没有返回语句,编译器将会在最后的语句之后插入返回0的语句,返回 0 表示程序运行成功,其他大部分返回值则表示失败。非 0 返回值的意义因机器不同而不同,为了使返回值独立于机器,cstdlib 头文件定义了两个预处理变量,分别用于表示程序运行成功和失败:
#include <cstdlib>
int main()
{
if (some_failure)
return EXIT_FAILURE;
else
return EXIT_SUCCESS;
}
我们的代码不再需要使用那些依赖于机器的精确返回值。相应地,这些值都
在 cstdlib 库中定义,我们的代码不需要做任何修改。

2.返回非引用类型
函数的返回值用于初始化在调用函数处创建的临时对象。在求解表达式时,如果需要一个地方储存其运算结果,编译器会创建一个没有命名的对象,这就是临时对象。在英语中,C++ 程序员通常用 temporary 这个术语来代替 temporaryobject。
用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。当函数返回非引用类型时,其返回值既可以是局部对象,也可以是求解表达式的结果。
例如,下面的程序提供了一个计数器、一个单词 word 和单词结束字符串
ending,当计数器的值大于 1 时,返回该单词的复数版本:
// return plural version of word if ctr isn't 1
string make_plural(size_t ctr, const string &word,const string &ending)
{
return (ctr == 1) ? word : word + ending;
}
这个函数要么返回其形参 word 的副本,要么返回一个未命名的临时string 对象,这个临时对象是由字符串 word 和 ending 的相加而产生的。这两种情况下,return 都在调用该函数的地方复制了返回的 string 对象。

3.返回引用
没有复制返回对象。

4.千万不要返回局部对象引用
理解引用的定义,就会知道,返回后局部对象会被释放,返回的引用也就指向不确定的内存,所以在返回引用时,请思考这个对象指向调用前的那个对象

5.引用返回左值
返回引用的函数可以返回一个左值,可以在任何使用左值的地方使用,例:
char &get_val(string &str, string::size_type ix)
{
return str[ix];
}
int main()
{
string s("a value");
cout << s << endl; // prints a value
get_val(s, 0) = 'A'; // changes s[0] to A
cout << s << endl; // prints A value
return 0;
}
6.返回指针
函数的返回类型可以是大多数类型,但是需要注意不要返回指向局部对象的指针。

6.3.3 递归
直接或间接调用自己的函数称为递归函数,递归函数必须定义一个终止条件;否则,函数就会“永远”递归下去,这意味着函数会一直调用自身直到程序栈耗尽。有时候,这种现象称为“无限递归错误”。mian函数不能调用自身。

6.4 函数声明
函数声明由函数返回类型、函数名和形参列表组成。形参列表必须包括形参类型,但是不必对形参命名。这三个元素被称为函数原型,函数原型描述了函数的接口。函数原型为函数定义的程序员和使用函数的程序员提供了接口。

函数声明放在头文件中
1.为函数使用处提供了函数统一的形式 2.便于修改函数 3.编译器将检查申明和定义是否不一致

默认实参
函数调用的实参按位置解析,默认实参只能用来替换函数调用缺少的尾部实参。
1.默认实参的初始化式
可以是任何适当类型的表达式,如果是表达式,省略的参数将在调用时解析表达式。
2.默认实参的约束
即可以在函数声明也可以在函数定义处指定默认实参,但只能只能为一个形参指定默认实参一次。一般在声明中指定。

6.5 局部对象
默认情况下,局部变量的生命期局限于所在函数的每次执行期间。只有当定义它的函数被调用时才存在的对象称为自动对象。自动对象在每次调用函数时创建和撤销。自动对象,包括形参,都在定义它们的块语句结束时撤销。
static 局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化。这种对象一旦被创建,在程序结束前都不会撤销。当定义静态局部对象的函数结束时,静态局部对象不会撤销。在该函数被多次调用的过程中,静态局部对象会持续存在并保持它的值。

6.6 内联函数
为小操作定义一个函数的好处是:
· 阅读和理解函数 shorterString 的调用,要比读一条用等价的条件表达式取代函数调用表达式并    解释它的含义要容易得多。
· 如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多。
· 使用函数可以确保统一的行为,每个测试都保证以相同的方式实现。
· 函数可以重用,不必为其他应用重写代码。
但是,将小操作 写成函数有一个潜在的缺点:调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作;调用前要先保存寄存器,并在返回时恢复;复制实参;程序还必须转向一个新位置执行。
inline 说明对于编译器来说只是一个建议,编译器可以选择忽略这个建议。一般来说,内联机制适用于优化小的、只有几行的而且经常被调用的函数。大多数的编译器都不支持递归函数的内联。一个 1200 行的函数也不太可能在调用点内联展开。
内联函数应该在头文件中定义,这一点不同于其他函数。inline 函数的定义对编译器而言必须是可见的,以便编译器能够在调用点内联展开该函数的代码。此时,仅有函数原型是不够的。在头文件中加入或修改 inline 函数时,使用了该头文件的所有源文件都必须重新编译。

6.7 类的成员函数
6.7.1 定义成员函数的函数体
编译器隐式的将定义在类内的函数当作内联函数,其实很容易明白,因为类定义在头文件,而内联函数也定义在头文件,恰好符合这种正规的用法。
每个成员函数都有一个额外的隐含的形参将该成员函数和调用这个函数的类的对象绑定在一起,就是this指针。
这样也就可以理解有些在类成员函数声明的形参表花括号之后的const 代表什么意思,这就是指定,隐含的形参 this 指针为 指向该类const对象的指针(注意与指向该类对象的const指针区分),当遇到这种在形参表花括号之后有const的函数 或者成为常量成员函数时,该函数不能修改调用该函数的对象(毕竟this指向的const对象)
this指针不能显式定义在形参列表,这样做事错误的。调用时也不用显示写出,但是可以显式写出。
6.7.1 类的构造函数
类的局部对象,调用类的默认构造函数初始化,如果没有定义默认构造函数,将使用合成的默认构造函数,但是合成的构造函数,不会初始化内置类型的数据成员。

6.8 重载函数
出现在相同作用域中的两个函数,如果具有相同的名字而形参表不同,则称为重载函数。
任何程序都仅有一个 main 函数的实例。main 函数不能重载。

函数重载和重复声明的区别
如果两个函数声明的返回类型和形参表完全匹配,则将第二个函数声明视为第一个的重复声明。如果两个函数的形参表完全相同,但返回类型不同,则第二个声明是错误的:
Record lookup(const Account&);
bool lookup(const Account&); // error: only return type is different
函数不能仅仅基于不同的返回类型而实现重载。

形参定义为 const。这种差异并不影响传递至函数的对象,所以不是重载,形参与 const 形参的等价性仅适用于非引用形参。有 const 引用形参的函数与有非 const 引用形参的函数是不同的。类似地,如果函数带有指向 const 类型的指针形参,则与带有指向相同类型的非 const 对象的指针形参的函数不相同。

6.8.1. 重载与作用域
与变量类似,在局部声明的函数将屏蔽全局声明的同名函数,所以使用重载应放在同一的作用域,否则可能造成函数的覆盖(类比变量覆盖)。另外,c++名字的查找发生在类型检查之前。

6.8.2. 函数匹配与实参转换
匹配结果有三种可能:
1. 编译器找到与实参最佳匹配的函数,并生成调用该函数的代码。
2. 找不到形参与函数调用的实参匹配的函数,在这种情况下,编译器将给出编译错误信息。
3. 存在多个与实参匹配的函数,但没有一个是明显的最佳选择。这种情况也是错误的,该调用        具有二义性。
匹配时可能会发生,实参类型的转换。

6.8.3. 重载确定的三个步骤
  • 候选函数
  • 选择可行函数
  • 寻找最佳匹配(如果有的话)
含有多个形参的重载确定:
1. 其每个实参的匹配都不劣于其他可行函数需要的匹配。
2. 至少有一个实参的匹配优于其他可行函数提供的匹配。
如果满足一个则匹配成功,否则匹配就会发生二义性错误,这是要想成功调用应该强制转换参数,但这也意味着重载函数形参集合不合理!

6.8.4. 实参类型转换
为了确定最佳匹配,编译器将实参类型到相应形参类型转换划分等级。转换等级以降序排列如下:
1. 精确匹配。实参与形参类型相同。
2. 通过类型提升实现的匹配(第 4.12.2 节)。
3. 通过标准转换实现的匹配(第 4.12.3 节)。
4. 通过类类型转换实现的匹配(第 13.9 节将介绍这类转换)。

重载和const 形参
仅当形参是引用或指针时,形参是否为 const 才有影响。可基于函数的引用形参是指向       const 对象还是指向非 const 对象,实现函数重载。

6.9 指向函数的指针
// pf points to function returning bool that takes two const string references
bool (*pf)(const string &, const string &);
//*pf 两侧的圆括号是必需的:
// declares a function named pf that returns a bool*
bool *pf(const string &, const string &);

用 typedef 简化函数指针的定义
函数指针类型相当地冗长。使用 typedef 为指针类型定义同义词,可将函数指针的使用大大简化:
typedef bool (*cmpFcn)(const string &, const string &);
该定义表示 cmpFcn 是一种指向函数的指针类型的名字。该指针类型为“指向返回 bool 类型并带有两个 const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用       cmpFcn 即可。

指向函数的指针的初始化和赋值
在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数:
// compares lengths of two strings
bool lengthCompare(const string &, const string &);
除了用作函数调用的左操作数以外,对 lengthCompare 的任何使用都被解释为如下类型的指针:
bool (*)(const string &, const string &);
可使用函数名对函数指针做初始化或赋值:
cmpFcn pf1 = 0; // ok: unbound pointer to function
cmpFcn pf2 = lengthCompare;   // ok: pointer type matches function's type
pf1 = lengthCompare;         // ok: pointer type matches function's type
pf2 = pf1; // ok: pointer types match
此时,直接引用函数名等效于在函数名上应用取地址操作符:
cmpFcn pf1 = lengthCompare;
cmpFcn pf2 = &lengthCompare;
函数指针只能通过同类型的函数或函数指针或 0 值常量表达式进行初始化或赋值。指向不同函数类型的指针之间不存在转换。

通过指针调用函数
指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数:
cmpFcn pf = lengthCompare;
lengthCompare("hi", "bye"); // direct call
pf("hi", "bye"); // equivalent call: pf1 implicitly dereferenced
(*pf)("hi", "bye"); // equivalent call: pf1 explicitlydereferenced

函数指针形参
函数的形参可以是指向函数的指针。这种形参可以用以下两种形式编写:
/* useBigger function's third parameter is a pointer to function
* that function returns a bool and takes two const string references
* two ways to specify that parameter:
*/
// third parameter is a function type and is automatically treated as a pointer to function
void useBigger(const string &, const string &, bool(const string &, const string &));
// equivalent declaration: explicitly define the parameter as a pointer to function
void useBigger(const string &, const string &, bool (*)(const string &, const string &));

返回指向函数的指针
函数可以返回指向函数的指针,但是,正确写出这种返回类型相当不容易:
// ff is a function taking an int and returning a function pointer
// the function pointed to returns an int and takes an int* and an int
int (*ff(int))(int*, int);
阅读函数指针声明的最佳方法是从声明的名字开始由里而外理解
要理解该声明的含义,首先观察:
ff(int)
将 ff 声明为一个函数,它带有一个 int 型的形参。该函数返回
int (*)(int*, int);
它是一个指向函数的指针,所指向的函数返回 int 型并带有两个分别是
int* 型和 int 型的形参。
使用 typedef 可使该定义更简明易懂:
// PF is a pointer to a function returning an int, taking an int* and an int
typedef int (*PF)(int*, int);
PF ff(int); // ff returns a pointer to function
允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。
具有函数类型的形参所对应的实参将被自动转换为指向相应函数类型的指针。但是,当返回的是函数时,同样的转换操作则无法实现:
// func is a function type, not a pointer to function!
typedef int func(int*, int);
void f1(func); // ok: f1 has a parameter of function type
func f2(int); // error: f2 has a return type of function type
func *f3(int); // ok: f3 returns a pointer to function type

指向重载函数的指针
C++ 语言允许使用函数指针指向重载的函数:
extern void ff(vector<double>);
extern void ff(unsigned int);
// which function does pf1 refer to?
void (*pf1)(unsigned int) = &ff; // ff(unsigned)
指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误:
// error: no match: invalid parameter list
void (*pf2)(int) = &ff;
// error: no match: invalid return type
double (*pf3)(vector<double>);
pf3 = &ff;

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
高级指针话题
返回类型和return语句
C++ Primer第六章函数
C++ primer学习笔记一
C 避坑指南
C/C 程序设计员应聘常见面试试题 strcpy
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服