按值或const ref传递指针?

时间:2013-10-31 15:18:13

标签: c++

简而言之,通过值或const引用传递指针是否更好?

我写了一个简单的函数来探索:

void foo(int* v) { std::cout << *v << endl; }

void foo(int* const& v) { std::cout << *v << endl; }

我试着看一下生成的组件,但我不是特别擅长组装,所以我不确定我是否理解其中的区别。但是有区别。在第一种情况下,我们得到:

pushq   %rbp
pushq   %rbx
subq    $8, %rsp
movl    (%rdi), %esi
movl    std::cout, %edi
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

const&案例中,我们再进行一次操作:

pushq   %rbp
pushq   %rbx
subq    $8, %rsp
movq    (%rdi), %rax
movl    std::cout, %edi
movl    (%rax), %esi
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

这种差异意味着什么(三个mov而不是两个),这意味着什么? (基本上,我有一个结构Foo<T>,其中T可能是一个原始指针,我想知道我的函数bar(const T&)是否应该是bar(typename boost::call_traits<T>::type)。)。

3 个答案:

答案 0 :(得分:9)

按值传递指针,除非您需要引用语义。

通过引用传递几乎可以通过传递指针来实现。您将传递与指针本身相同数量的数据,但会引入额外的间接级别,因此它的效率可能低于传递值。

话虽如此,差异可能很小;所以对于通用代码,通过const引用更简单,除非你真的需要在单个指令的级别进行微优化。如果您这样做,正如您所说,boost::call_traits可以提供帮助。

答案 1 :(得分:1)

通过引用传递指针将执行以下操作:

Address: 0x00  -  42   (int)
Address: 0x11  -  0x00 (int*)
Address: 0x22  -  0x11 (int* const&)

这基本上是编译器为int * const&amp;生成的内容。实施明智,它可能最终成为int **。

因此,按值传递指针最终会更有效率,因为您将直接复制int的地址,而不会产生第三行的开销。

答案 2 :(得分:0)

对于指针,按值传递。根据定义,将指针传递给指针(这将是引擎盖下发生的事情)不能比传递指针更有效。汇编程序中的额外行(我对此知之甚少)表明它实际上对您来说效率较低。