c++ - 在这种情况下,有人可以解释 "reference"和 "pointer"之间的区别吗?

标签 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打开


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

最佳答案

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

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
}

它不起作用,因为它需要一个函数,而不是函数指针。出于与数组 answer 拒绝指针相同的原因,这也拒绝指针。你必须直接传递“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 以不同方式对待它们以进行内联 - 但我也怀疑这是因为函数引用很少出现。

关于c++ - 在这种情况下,有人可以解释 "reference"和 "pointer"之间的区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1516958/

相关文章:

c++ - 在 Visual Studio 2010 和 11 之间共享 C++ 解决方案

c++ - 文件输入问题 [C++]

c++ - 将 nullptr QVariant 与空 QString 进行比较会在 Qt5.9 和 Qt5.12 中给出不同的输出

C++ 如何将对象 move 到 nullptr

c++ - 当指向子类的指针传递给函数时,为什么引用的是类而不是子类?

c - 为什么需要在 C 中用 * 定义对指针的引用?

c++ - 是否可以更改 C++ std::set 的比较器?

将指向字符串的指针作为函数参数传递时发生类型冲突错误

c++ - 为什么我不能像这样: int *p = 6;?直接给int指针赋值

c++ - 为什么第二个代码有效而第一个无效?