在C ++中调用(调用)函数的方式有多少?

时间:2015-02-24 06:34:07

标签: c++ function

我知道调用函数的一种方法:

func(x, y);

有更多方法可以调用函数吗?

4 个答案:

答案 0 :(得分:5)

可以调用函数

  • 显式地,通过在指定函数之后提供参数括号(在构造函数的情况下,这显然不是正式的正确措辞,因为它们没有名称,但无论如何),

    < / LI>
  • 隐式地,特别是析构函数和默认构造函数,还有隐式类型转换,

  • 通过函数调用运算符()以外的运算符,特别是复制赋值运算符=和解除引用运算符->

  • 在展示位置new表达式中,通过在new之后放置一个参数括号来调用指定的分配函数(不确定这是否作为一种单独的方式)。

此外,图书馆设施当然可以为您调用功能。

我认为以上列表是详尽无遗的,但我不确定。我记得Andrei Alexandrescu在他的 Modern C ++ Design 一书中列举了产生 callable thingies 的结构,并且让我感到惊讶。因此,上述内容可能并非详尽无遗。

答案 1 :(得分:2)

可以调用任意函数:

  • 使用f(arguments...)表示法

  • 通过指向该函数的指针(无论是成员还是非 - )

  • 通过std::function - (将检查实现的左侧未指定,但我希望它使用指向函数的指针或指向成员函数的指针,因此没有新的语言功能)

在某些情况下也会调用特定于类的函数:

  • 在堆栈上创建对象时,以及动态初始化静态/全局或特定于线程的对象或动态分配的对象,或使用放置new时,以及在计算表达式时调用构造函数

  • 当对象离开作用域时调用析构函数,delete d,线程退出,临时销毁,以及析构函数明确调用ala x.~X()

  • 在表达式评估期间,可以调用各种运算符([]+===<等)

任意非成员函数可以通过以下方式运行:

    由于早期std::atexit()std::at_quick_exit()调用,
  • 可能会运行,如果他们抛出std::terminate可能会运行

  • 线程创建和异步信号(接口再次接受指向函数的指针,并且没有理由认为任何实现已经或将使用任何其他技术来实现调度)

在特定情况下会触发特定功能:

  • main()由运行时执行

  • 违反动态异常规范时,会调用
  • std::unexpectedstd::unexpected_handlerstd::terminate

也可以使用setjmplongjmp“跳”回函数......与调用函数不完全相同。

虽然不是真正的“C ++”,但也可以使用内联汇编语言/链接汇编程序来编写函数执行,写入可执行内存。

答案 2 :(得分:1)

C ++是一种相当灵活的语言,因此这是一个非常模糊的问题,因为可以有100种不同的方式来调用函数&#34;鉴于不允许的限制。

请记住,函数实际上只是位于内存中某处的代码块。 &#34;呼叫&#34;一个函数在某种程度上如下:

  1. 将所需参数放入正确的寄存器/堆栈位置
  2. 将PC(程序计数器)移动到内存中函数的位置(这通常通过&#34;调用&#34;类型机器指令完成)
  3. 从技术上讲,可能会有一些&#34;清理&#34;代码取决于编译器如何实现函数。
  4. 最后,所有方法都会以某种方式发生。

    这里或许并非100%相关,但请记住,在C ++中,函数可以是类的成员。

    class MyClass{
     public:
     void myFunction(int A);
    }
    

    通常在这种情况下发生的是类对象作为第一个参数传递。

    所以函数调用:

    myObject.myFunction(A) 
    is in a way equivalent to calling:
    myFunction(myObject,A)
    

    如果你看一下函数对象,你会看到这种行为。 Function objects reference

    好的,所以这里有一个简短的清单:

    1. 通常调用函数myFunc(a,b);
    2. 函数指针。 typedef int(* funcP)(int,in);
    3. 功能对象。重载()运算符使您的对象可调用。
    4. C ++ 11 std :: function在很大程度上取代了函数指针,我建议你看看它们是如何工作的
    5. lambda函数在某种程度上也是一种函数。
    6. 代表可以有各种各样的实现。
    7. callback
    8. 的概念一样,函数指针和委托等事情多次使用
    9. 您可以使用多播委托。 (例如,boost.signals2或Qt信号和插槽)
    10. 您可以绑定到DLL中的函数并调用它。 DLL calling
    11. 有多种方法可以在进程和网络之间调用函数。通常被称为rpc实现。
    12. 在线程环境中,事情可能也会变得更有趣,因为您可能希望在不同的线程中调用函数。

      • 参见Qt Signals&amp;插槽螺纹连接
      • 也可以使用线程池。 link1 link2

      最后,我认为提及元编程和RTTI的想法是一个好主意。这并不像c#这样的语言那样强烈支持。 如果要手动实现,则可以在运行时搜索可用功能列表并调用一个。通过这种方法,可以在运行时匹配函数与字符串名称。这在某种程度上得到了Qt的MOC系统的支持。

答案 3 :(得分:0)

我们在计算什么是另一种方式?如果我有一个类foo的成员函数,那么我可以这样称呼它:

foo.func(x, y);

如果我有指向foo的指针,我会这样做

foo->func(x, y);

如果我有一个派生自foo的类栏,我可以用初始化列表调用foo的构造函数

bar::bar(const int x, const int y) : foo(x, y) {}

毕竟,构造函数只是一个函数。