函数调用运算符:()

函数调用是一种 postfix-expression,由计算结果为函数或可调用对象后跟函数调用运算符 () 的表达式构成。 对象可以声明 operator () 函数,该函数为对象提供函数调用语义。

语法

postfix-expression
postfix-expression ( argument-expression-list opt )

注解

函数调用运算符的参数来自 argument-expression-list,由逗号分隔的表达式列表。 这些表达式的值传递给函数作为自变量。 argument-expression-list 可为空。 在 C++ 17 之前,函数表达式和参数表达式的计算顺序未指定,并且可能按任何顺序发生。 在 C++17 及更高版本中,在任意参数表达式或默认参数之前计算函数表达式。 参数表达式在不确定序列中求值。

postfix-expression 计算结果为要调用的函数。 它可以采用任一形式:

  • 函数标识符,在当前范围或提供的任何函数参数的范围内可见,
  • 计算结果为函数、函数指针、可调用对象或对一个对象的引用的表达式,
  • 成员函数访问器,显式或隐含,
  • 指向成员函数的取消引用指针。

postfix-expression 可以是重载函数标识符或重载的成员函数访问器。 重载解析的规则决定了要调用的实际函数。 如果成员函数为虚拟函数,则运行时确定要调用的函数。

一些示例声明:

  • 函数返回类型 T。 示例声明如下

    T func( int i );
    
  • 指向函数返回类型 T 的指针。 示例声明如下

    T (*func)( int i );
    
  • 对函数返回类型 T 的引用。 示例声明如下

    T (&func)(int i);
    
  • 指向成员的指针函数取消引用返回类型 T。 示例函数调用如下

    (pObject->*pmf)();
    (Object.*pmf)();
    

示例

以下示例调用带有三个自变量的标准库函数 strcat_s

// expre_Function_Call_Operator.cpp
// compile with: /EHsc

#include <iostream>
#include <string>

// C++ Standard Library name space
using namespace std;

int main()
{
    enum
    {
        sizeOfBuffer = 20
    };

    char s1[ sizeOfBuffer ] = "Welcome to ";
    char s2[ ] = "C++";

    strcat_s( s1, sizeOfBuffer, s2 );

    cout << s1 << endl;
}
Welcome to C++

函数调用结果

除非函数被声明为引用类型,否则函数调用的计算结果为右值。 具有引用返回类型的函数的计算结果为左值。 这些函数可以在赋值语句的左侧使用,如下所示:

// expre_Function_Call_Results.cpp
// compile with: /EHsc
#include <iostream>
class Point
{
public:
    // Define "accessor" functions as
    // reference types.
    unsigned& x() { return _x; }
    unsigned& y() { return _y; }
private:
    unsigned _x;
    unsigned _y;
};

using namespace std;
int main()
{
    Point ThePoint;

    ThePoint.x() = 7;           // Use x() as an l-value.
    unsigned y = ThePoint.y();  // Use y() as an r-value.

    // Use x() and y() as r-values.
    cout << "x = " << ThePoint.x() << "\n"
         << "y = " << ThePoint.y() << "\n";
}

前面的代码定义一个称作 Point 的类,该类包含表示 xy 坐标的专用数据对象。 必须修改这些数据对象,并且必须检索其值。 该程序只是针对此类的多个设计之一;另一种可能的设计是使用 GetXSetX 函数或使用 GetYSetY 函数。

返回类类型的函数、指向类类型的指针或对类类型的引用可以用作成员选择运算符的左操作数。 以下代码是合法的:

// expre_Function_Results2.cpp
class A {
public:
   A() {}
   A(int i) {}
   int SetA( int i ) {
      return (I = i);
   }

   int GetA() {
      return I;
   }

private:
   int I;
};

A func1() {
   A a = 0;
   return a;
}

A* func2() {
   A *a = new A();
   return a;
}

A& func3() {
   A *a = new A();
   A &b = *a;
   return b;
}

int main() {
   int iResult = func1().GetA();
   func2()->SetA( 3 );
   func3().SetA( 7 );
}

可以递归方式调用函数。 有关函数声明的详细信息,请参阅函数。 相关材料见翻译单元和链接

另请参阅

后缀表达式
C++ 内置运算符、优先级和关联性
函数调用