在函数调用中发送 QStrings 的最佳方式是啥?
Posted
技术标签:
【中文标题】在函数调用中发送 QStrings 的最佳方式是啥?【英文标题】:Whats the best way to send QStrings in a function call?在函数调用中发送 QStrings 的最佳方式是什么? 【发布时间】:2011-01-07 10:34:41 【问题描述】:我想知道在 QT 中将 Qstring 作为参数发送给函数的最有效和最实用的方法是什么。我想使用参考。问题是我还想在函数本身中实例化该字符串,例如:
这是函数原型:
void myFunction(QString & theMsg);
这是函数调用:
myFunction(tr("Hello StringWorld"));
现在function tr()
返回一个 QString 但它不适用于引用(我知道为什么)。
我必须这样做:
QString theQstr("Hello StringWorld");
myFunction(theQstr);
是否有更简单的方法可以在仍然使用引用的同时执行此操作,或者我可以将函数参数更改为使用 QString 并且仍然有效吗?
【问题讨论】:
这个怎么样:myFunction(QString("Hello StringWorld")); 生成编译消息。我认为这是因为这只会生成一个返回值,而没有任何具体的参考。 此链接可能会有所帮助:Right_way_to_pass_QString_to_methods How to pass objects to functions in C++? 的可能重复 这个问题是关于QString
的事实并没有改变拇指的基本规则。
【参考方案1】:
QString 在幕后使用 COW(写入时复制),因此即使您使用这样的签名,也不会复制实际的字符串:
void myFunction(QString theMsg)
(直到你修改它)。
如果你绝对想要一个引用,我会使用 const& 除非你打算修改输入参数。
void myFunction(QString const& theMsg)
【讨论】:
不,那太好了,谢谢!这就是我想知道的。所以它实际上与 Mac 上 Objective-C 中的 NSString 做同样的事情。 如果您查看 Qt 源代码,您会发现 Qt 本身倾向于将 Qt 类型作为 const T& 传递给函数。即使他们使用 COW,复制类的开销仍然比仅传递引用要多一些。 @Colin 你能详细说明一下开销吗?我只是查看了源代码,而 QString 只是指针的包装器。我确定了一个QString
和一个const QString&
sizeof(),它们都是 4 个字节。由于 QString 基本上是一个指针本身(并且 refs 是有效的指针),为什么将指针传递给指针而不是仅仅传递指针本身会更有效?听起来 const-ref 的效率会稍低...
@Colin C++ 编译器在编译时验证复制构造函数的存在;这不会即时发生(c++ 不是动态的解释语言)。此外,C++ 编译器非常非常擅长优化函数调用。我做了一些研究,看起来开销是由于引用计数,所以基本上它相当于一个增量操作(增加引用计数)、一个复制操作(复制包装的指针)和一个比较操作(是ref count > 0?我们需要释放指针吗?)。所以,是的,这是一些更大的操作......
写入时复制对象仍然必须维护指向数据的指针和引用计数(原子递增/递减),并通过复制构造函数和析构函数运行。因此,即使它的效率相当高,在可能的地方通过引用传递仍然更有效。如果编译器知道它不需要对参数做任何事情,它也可能使某些内联函数为零成本。【参考方案2】:
最有效和实用的方法是使用 const 引用。 QString COW 将比通过引用传递慢,但比常规副本快。
【讨论】:
为什么? [更多字符使评论有效]【参考方案3】:当您传递 QString 时,调用站点必须先调用 QString 复制 ctor,然后再调用 dtor:两者都意味着原子引用计数操作(不可忽略),以及更多生成的汇编代码。因此更慢和更大的代码(我在这里没有提到不太常见的 std::move 场景)。
另一方面,当你传递一个 const QString& 时,在被调用的站点上,有一个双重间接来访问字符:一个指向指针的指针。因此,这比传递 QString 慢,尤其是在频繁使用 QString 参数的情况下。
我建议始终传递一个 const QString&,如果您需要在被调用端获得最大速度,请在此处制作一个 QString 副本,并访问此本地副本以避免双重间接(更快,生成的代码更少)。
【讨论】:
以上是关于在函数调用中发送 QStrings 的最佳方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章
通过 Python Google Cloud Function 发送电子邮件的最佳方式是啥?
当 API 调用需要以纯文本形式发送密码时,将密码存储在数据库中的最佳方法是啥?