Team LiB
Previous Section Next Section

7.9. Pointers to Functions

7.9. 指向函数的指针

A function pointer is just thata pointer that denotes a function rather than an object. Like any other pointer, a function pointer points to a particular type. A function's type is determined by its return type and its parameter list. A function's name is not part of its type:

函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关:

     // pf points to function returning bool that takes two const string references
     bool (*pf)(const string &, const string &);

This statement declares pf to be a pointer to a function that takes two const string& parameters and has a return type of bool.

这个语句将 pf 声明为指向函数的指针,它所指向的函数带有两个 const string& 类型的形参和 bool 类型的返回值。

The parentheses around *pf are necessary:

*pf 两侧的圆括号是必需的:


     // declares a function named pf that returns a bool*
     bool *pf(const string &, const string &);

Using Typedefs to Simplify Function Pointer Definitions

用 typedef 简化函数指针的定义

Function pointer types can quickly become unwieldy. We can make function pointers easier to use by defining a synonym for the pointer type using a typedef (Section 2.6, p. 61):

函数指针类型相当地冗长。使用 typedef 为指针类型定义同义词,可将函数指针的使用大大简化:(第 2.6 节):

     typedef bool (*cmpFcn)(const string &, const string &);

This definition says that cmpFcn is the name of a type that is a pointer to function. That pointer has the type "pointer to a function that returns a bool and takes two references to const string." When we need to use this function pointer type, we can do so by using cmpFcn, rather than having to write the full type definition each time.

该定义表示 cmpFcn 是一种指向函数的指针类型的名字。该指针类型为“指向返回 bool 类型并带有两个 const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用 cmpFcn 即可,不必每次都把整个类型声明全部写出来。

Initializing and Assigning Pointers to Functions

指向函数的指针的初始化和赋值

When we use a function name without calling it, the name is automatically treated as a pointer to a function. Given

在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数:

     // compares lengths of two strings
     bool lengthCompare(const string &, const string &);

any use of lengthCompare, except as the left-hand operand of a function call, is treated as a pointer whose type is

除了用作函数调用的左操作数以外,对 lengthCompare 的任何使用都被解释为如下类型的指针:

     bool (*)(const string &, const string &);

We can use a function name to initialize or assign to a function pointer:

可使用函数名对函数指针做初始化或赋值:

     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

Using the function name is equivalent to applying the address-of operator to the function name:

此时,直接引用函数名等效于在函数名上应用取地址操作符:

     cmpFcn pf1 = lengthCompare;
     cmpFcn pf2 = &lengthCompare;

A function pointer may be initialized or assigned only by a function or function pointer that has the same type or by a zero-valued constant expression.

函数指针只能通过同类型的函数或函数指针或 0 值常量表达式进行初始化或赋值。

Initializing a function pointer to zero indicates that the pointer does not point to any function.

将函数指针初始化为 0,表示该指针不指向任何函数。

There is no conversion between one pointer to function type and another:

指向不同函数类型的指针之间不存在转换:

     string::size_type sumLength(const string&, const string&);
     bool cstringCompare(char*, char*);
     // pointer to function returning bool taking two const string&
     cmpFcn pf;
     pf = sumLength;      // error: return type differs
     pf = cstringCompare; // error: parameter types differ
     pf = lengthCompare;  // ok: function and pointer types match exactly

Calling a Function through a Pointer

通过指针调用函数

A pointer to a function can be used to call the function to which it refers. We can use the pointer directlythere is no need to use the dereference operator to call the function

指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数:

     cmpFcn pf = lengthCompare;
     lengthCompare("hi", "bye"); // direct call
     pf("hi", "bye");            // equivalent call: pf1 implicitly dereferenced
     (*pf)("hi", "bye");         // equivalent call: pf1 explicitly dereferenced

If the pointer to function is uninitialized or has a value of zero, it may not be used in a call. Only pointers that have been initialized or assigned to refer to a function can be safely used to call a function.

如果指向函数的指针没有初始化,或者具有 0 值,则该指针不能在函数调用中使用。只有当指针已经初始化,或被赋值为指向某个函数,方能安全地用来调用函数。

Function Pointer Parameters

函数指针形参

A function parameter can be a pointer to function. We can write such a parameter in one of two ways:

函数的形参可以是指向函数的指针。这种形参可以用以下两种形式编写:


     /* 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 &));

Returning a Pointer to Function

返回指向函数的指针

A function can return a pointer to function, although correctly writing the return type can be a challenge:

函数可以返回指向函数的指针,但是,正确写出这种返回类型相当不容易:

     // 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);

The best way to read function pointer declarations is from the inside out, starting with the name being declared.

阅读函数指针声明的最佳方法是从声明的名字开始由里而外理解。

We can figure out what this declaration means by observing that

要理解该声明的含义,首先观察:

     ff(int)

says that ff is a function taking one parameter of type int. This function returns

ff 声明为一个函数,它带有一个 int 型的形参。该函数返回

     int (*)(int*, int);

a pointer to a function that returns an int and takes two parameters of type int* and an int.

它是一个指向函数的指针,所指向的函数返回 int 型并带有两个分别是 int* 型和 int 型的形参。

Typedefs can make such declarations considerably easier to read:

使用 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

We can define a parameter as a function type. A function return type must be a pointer to function; it cannot be a function.

允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。

An argument to a parameter that has a function type is automatically converted to the corresponding pointer to function type. The same conversion does not happen when returning a 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

Pointers to Overloaded Functions

指向重载函数的指针

It is possible to use a function pointer to refer to an overloaded function:

C++ 语言允许使用函数指针指向重载的函数:

     extern void ff(vector<double>);
     extern void ff(unsigned int);

     // which function does pf1 refer to?
     void (*pf1)(unsigned int) = &ff; // ff(unsigned)

The type of the pointer and one of the overloaded functions must match exactly. If no function matches exactly, the initialization or assignment results in a compile-time error:

指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误:

     // error: no match: invalid parameter list
     void (*pf2)(int) = &ff;

     // error: no match: invalid return type
     double (*pf3)(vector<double>);
     pf3 = &ff;

Team LiB
Previous Section Next Section