C++ 和 QT4.5 - 传递 const int& 过大?通过引用传递是不是有助于信号/插槽?
Posted
技术标签:
【中文标题】C++ 和 QT4.5 - 传递 const int& 过大?通过引用传递是不是有助于信号/插槽?【英文标题】:C++ and QT4.5 - is passing a const int& overkill? Does pass by reference helps in signals/slots?C++ 和 QT4.5 - 传递 const int& 过大?通过引用传递是否有助于信号/插槽? 【发布时间】:2010-11-22 22:06:45 【问题描述】:两个问题在这里合二为一……
对于实时视频处理应用程序,我有许多每帧调用多次的函数。接受关于 const 的建议并通过引用传递,函数的签名有点像这样
void processSomething(const int& value);
当我不断输入几个额外的字符时,我想知道这是否有点矫枉过正。
第二个问题,关于按引用传递的主题,在 QT 的槽/信号机制中,按引用传递是否有助于防止像在正常函数调用中那样复制对象?
【问题讨论】:
我读过的所有关于 const 和通过引用传递的建议都包含“除了内置类型”的附带条件。 【参考方案1】:是的,这有点矫枉过正,实际上会导致比按值传递 int 的代码更慢。一个 int 是四个字节;引用(本质上是内存地址)或者也是四个字节(在 32 位机器上)或八个字节(在 64 位机器上)。因此,您实际上可能需要将 更多 信息传递给函数——此外,您还有取消引用该引用的开销。
但是,如果您要传递大于 int 的内容,则使用 const 引用会更有效,因为您可以只传递 4 或 8 个字节,而不必复制整个对象。
编辑关于Qt:是的,如果槽接受一个对象的const引用,那么这样做的原因是为了节省复制对象的开销。
【讨论】:
【参考方案2】:首先——两者的区别
void processSomething(const int& value); void processSomething(int value);is:通常一个 const 引用是通过传递一个指针来传递的,另一个是通过复制传递的。调用后(从调用方),结果是相等的。调用不会更改您传递给函数的任何内容。
在函数内部,您也不会看到任何差异(至少在 int 上)。在 Objects 上,你当然只能使用 const 函数。
在性能方面 - 将 const 引用传递给 int 可能(或可能不会)更慢,具体取决于编译器和优化。编译器可以(理论上)将 const 引用的传递优化为按值传递,但我不知道它是否这样做。当然,使用指向整数而不是值的指针会更慢。
有关更多信息,请参阅: When to use pointers, and when not to use them
在阅读了其他链接的帖子后 - 编译器无法在多线程环境中对其进行优化。至少在 MT 环境中,const int& 和 int 调用之间存在真正的差异。为该链接 +1。
【讨论】:
实际上,您也不能在const int& value
上使用非常量函数。也就是说,如果我有void foo(int&)
,那么processSomething(const int& value) foo(value);
是非法的,而processSomething(int value) foo(value);
是合法的。【参考方案3】:
是的,通过引用传递有助于防止复制对象。但是编译器可能会决定完全优化它并按值传递,如果它产生相同的效果。如果函数和调用站点在同一个翻译单元中,这种优化通常是可能的,但一些编译器可以做更多的全局优化——如果你愿意,可以检查发出的程序集。
这就是为什么你真的不应该通过引用传递原始类型,如果你关心性能并且除非你真的有理由这样做。有关该问题的讨论,请参见 What is the use of passing const references to primitive types?。
【讨论】:
编译器可以进行这种优化的唯一情况是调用者和被调用者在同一个翻译单元中。 其实不是,Visual C++ 证明了这一点。他们称之为链接时间代码生成。 ISO C++ 没有指定预处理器、编译器、链接器和运行时的确切职责。以上是关于C++ 和 QT4.5 - 传递 const int& 过大?通过引用传递是不是有助于信号/插槽?的主要内容,如果未能解决你的问题,请参考以下文章
小白学习C++ 教程八在C++指针传递引用和Const关键字
小白学习C++ 教程八在C++指针传递引用和Const关键字
C++核心准则边译边学-F.17 输入/输出参数传递非常量引用