在这种情况下,有人可以解释“参考”和“指针”之间的区别吗?

时间:2009-10-04 17:44:00

标签: c++ pointers reference

当我阅读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();
}

我尝试使用VC2008,它会在每种情况下产生不同的输出。奇怪的是,在函数指针的情况下,编译器会更好地优化代码:

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 个答案:

答案 0 :(得分:3)

这并不常见,因此可能只是VS团队没有添加规则来优化它。

答案 1 :(得分:3)

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

  

函数类型T的左值可以转换为“指向T的指针”的右值。结果是指向   功能。

答案 2 :(得分:3)

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

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
}

它不起作用,因为它需要一个函数,而不是一个函数指针。出于同样的原因,数组答案拒绝指针,这也拒绝指针。你必须直接传递“g”。

对于模板,它也很重要

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会以不同的方式对待内联 - 但我也怀疑它是因为函数引用似乎更少见。

答案 3 :(得分:-2)

引用(&amp;)和指针(*)之间的区别在于引用提供变量的地址或位置,指针指向存储在其中的地址的内存中的位置。

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.

我们可以得出结论,(&amp;变量)具有该内存位置的地址,* anyname指向存储在其内存中的地址......