代码之家  ›  专栏  ›  技术社区  ›  Khaled Alshaya

有人能解释一下在这种情况下“引用”和“指针”之间的区别吗?

  •  6
  • Khaled Alshaya  · 技术社区  · 16 年前

    litb answer to this question

    void execute( void (&func)() ) // func is passed by reference!
    {
        func();
    }
    

    最后一个函数和这个函数之间有什么区别吗:

    void execute( void (*func)() ) // func is passed by pointer!
    {
        func();
    }
    

    void print()
    {
        std::cout << "Hello References!";
    }
    void execute( void (&func)() ) // optimized
    {
        func();
    }
    int main()
    {
        00291020  call   print (291000h)
    }
    =========================================
    // In this case, the compiler removes all function calls in the code!
    void print() // optimized!
    {
        std::cout << "Hello Pointers!";
    }
    void execute( void (*func)() ) // optimized
    {
        func();
    }
    int main()
    {
        002F1005  push  offset string "Hello References!" (2F2124h) 
        002F100A  push  eax  
        002F100B  call  std::operator<<<std::char_traits<char> > (2F1150h) 
    }
    

    一定有区别,虽然我看不出来,对吧?

    注意:代码是使用VC2008编译的 /O2 /Ot 打开。


    编辑:: 我对函数引用和函数指针之间的任何区别都很感兴趣。我检查了生成的汇编代码,看看它在每种情况下是如何翻译的。

    4 回复  |  直到 8 年前
        1
  •  3
  •   Johannes Schaub - litb    16 年前

    对于语言差异(只保留下面的函数声明,因为这才是重要的)

    void execute( void (&func)() );
    
    void g();
    int main() {
      void (*fp)() = g;
      execute(fp); // doesn't work
      execute(&g); // doesn't work either
      execute(g); // works
    }
    

    template<typename T>
    void execute(T &t) { T u = t; u(); }
    
    template<typename T>
    void execute(T t) { T u = t; u(); }
    

    这两个彼此非常不同。如果你用 execute(g); 如上所述,第一个函数将尝试声明一个函数并用以下代码初始化它 t g

    void execute(void(&t)()) { void u() = t; u(); }
    

    现在,您可以初始化指向函数的引用和指针,但当然不能初始化函数本身。在第二定义中, T 将通过模板参数推导导出为函数指针类型,传递函数将隐式地将其转换为该指针参数类型。所以一切都会好起来的。


    我不知道为什么MSVC在内联时对它们有不同的处理方式,但我也怀疑这是因为函数引用出现的次数更少。

        2
  •  3
  •   Pete Kirkham    16 年前

    这不是一个常见的习语,所以可能只是VS团队没有添加规则来优化它。

        3
  •  3
  •   Kirill V. Lyadvinsky    16 年前

    我认为这是由于C++标准4.3:

    功能。

        4
  •  -2
  •   thkala jaxb    14 年前

    int *pointer;
    int variable;
    
    pointer = &variable; // assigning the address of variable to pointer 
    
    variable = 53;  // value of variable
    
    cout << *pointer; // This should output the value of the address where is pointing, in this
                      //  case 53, that is the value of variable to where is pointing.