在 C++ 中返回字符串的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10553091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to return string in C++?
提问by tonytony
My question is simple: if I have some class Man and I want to define member function that returns man's name, which of the following two variants shall I prefer?
我的问题很简单:如果我有一些类 Man 并且我想定义返回人名的成员函数,我应该更喜欢以下两种变体中的哪一种?
First:
第一的:
string name();
Second:
第二:
void name(/* OUT */ string &name);
The first variant is kind of inefficient because it makes unnecessary copies (local variable -> return value -> variable in the left part of assignment).
第一个变体有点低效,因为它会产生不必要的副本(局部变量 -> 返回值 -> 赋值左侧的变量)。
The second variant looks pretty efficient but it makes me cry to write
第二个变体看起来很有效,但写起来让我哭了
string name;
john.name(name);
instead of simple
而不是简单
string name(john.name());
So, what variant shall I prefer and what is the proper trade-off between efficiency and convenience/readability?
那么,我应该更喜欢哪种变体,效率和便利性/可读性之间的适当权衡是什么?
Thanks in advance.
提前致谢。
采纳答案by Mahmoud Al-Qudsi
It's a good question and the fact that you're asking it shows that you're paying attention to your code. However, the good news is that in this particular case, there's an easy way out.
这是一个很好的问题,你问这个问题表明你正在关注你的代码。然而,好消息是,在这种特殊情况下,有一个简单的方法。
The first, clean method is the correct way of doing it. The compiler will eliminate unnecessary copies, in most cases (usually where it makes sense).
第一个,干净的方法是正确的方法。在大多数情况下(通常在有意义的情况下),编译器会消除不必要的副本。
EDIT (6/25/2016)
编辑 (6/25/2016)
Unfortunately it seems that David Abaraham's site has been offline for a few years now and that article has been lost to the ethers (no archive.org copy available). I have taken the liberty of uploading my local copy as a PDF for archival purposes, and it can be found here.
不幸的是,David Abaraham 的网站似乎已经下线了几年,并且该文章已被以太坊遗失(没有可用的 archive.org 副本)。我冒昧地将我的本地副本作为 PDF 文件上传以供存档,可以在此处找到。
回答by juanchopanza
use the first variant:
使用第一个变体:
string name();
The compiler will most likely optimize out any unnecessary copies. See return value optimization.
编译器很可能会优化掉任何不必要的副本。请参阅返回值优化。
In C++11, move semantics means that you don't perform a full copy even if the compiler doesn't perform RVO. See move semantics.
在 C++11 中,移动语义意味着即使编译器不执行 RVO,您也不执行完整复制。请参阅移动语义。
Also bear in mind that if the alternative is
还要记住,如果替代方案是
void name(std::string& s);
then you have to specify very clearly what can happen to s
and what values it can have when passed to the function, and probably either do a lot of validity checking, or simply overwrite the input entirely.
那么您必须非常清楚地指定s
在传递给函数时会发生什么以及它可以具有哪些值,并且可能会进行大量有效性检查,或者只是完全覆盖输入。
回答by Mesop
Since you want to create a getter for a field of your class, maybe you should go like that: inline const std::string& name() const { return this->name; }
既然你想为你的类的一个字段创建一个 getter,也许你应该这样做: inline const std::string& name() const { return this->name; }
Since the name is returned as a const reference, it won't be modified outside the class, also no copy will be created by returning the name.
由于名称作为常量引用返回,因此不会在类外修改,也不会通过返回名称创建副本。
After that, if you want to manipulate the name you will have to do a copy.
之后,如果您想操纵名称,则必须进行复制。
回答by flumpb
I would go with the first. Return value optimization and C++11 will remove any copying overhead.
我会和第一个一起去。返回值优化和 C++11 将消除任何复制开销。
回答by DevSolar
Rule #1 of optimization: Measure, optimize, measure. Or, as Knuth said, "premature optimization is the root of all evil".
优化规则#1:测量、优化、测量。或者,正如 Knuth 所说,“过早的优化是万恶之源”。
Unless you have a strong indication that simply returning std::string
will significantly impact the performance of your software, just do so. If you can measurea significant impact, find the critical path, and optimize that. Don't make any funny, project-wide "optimizations" that likely result in little to no performance benefit, but negatively impact the readability, maintainability and robustness of your code.
除非你有强烈的迹象表明简单地返回std::string
会显着影响你的软件的性能,否则就这样做。如果你能衡量一个显著的影响,找到关键路径,优化那。不要进行任何有趣的、项目范围的“优化”,这可能会带来很少甚至没有性能优势,但会对代码的可读性、可维护性和健壮性产生负面影响。
回答by Nawaz
As we have move-semantics (in C++11), you can use this:
由于我们有移动语义(在 C++11 中),您可以使用它:
string name();
Even in C++03, this is almost good, as the compiler might optimize this (Search for Return Value Optimization).
即使在 C++03 中,这也几乎是好的,因为编译器可能会对此进行优化(搜索返回值优化)。
回答by Robert
I think you should use first variant. Because this is simple getter method and such getter/setter approach is used everywhere.
我认为你应该使用第一个变体。因为这是简单的 getter 方法,而且到处都使用这种 getter/setter 方法。