C++ 返回局部于函数的 std::string 的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3976935/
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
best way to return an std::string that local to a function
提问by Tony The Lion
In C++ what is the best way to return a function local std::string variable from the function?
在 C++ 中,从函数返回函数局部 std::string 变量的最佳方法是什么?
std::string MyFunc()
{
std::string mystring("test");
return mystring;
}
std::string ret = MyFunc(); // ret has no value because mystring has already gone out of scope...???
回答by Chubsdad
No. That is not true. Even if mystring
has gone out of scope and is destroyed, ret
has a copy of mystring as the function MyFunc
returns by value.
不,那不是真的。即使mystring
已经超出范围并被销毁,ret
也有一个 mystring 的副本作为函数MyFunc
按值返回。
回答by Kiril Kirov
There will be a problem if your code is like:
如果你的代码是这样的,就会有问题:
std::string& MyFunc()
{
std::string mystring("test");
return mystring;
}
So, the way you've written it is OK. Just one advice - if you can construct the string like this, I mean - you can do it in one row, it's sometimes better to do it like this:
所以,你写的方式没问题。只是一个建议 - 如果你可以像这样构造字符串,我的意思是 - 你可以在一行中完成,有时这样做会更好:
std::string MyFunc()
{
return "test";
}
Or if it's more "complicated", for ex:
或者如果它更“复杂”,例如:
std::string MyFunct( const std::string& s1,
const std::string& s2,
const char* szOtherString )
{
return std::string( "test1" ) + s1 + std::string( szOtherString ) + s2;
}
This will give a hintto your compiler to do more optimization, so it could do one less copy of your string (RVO).
这将提示您的编译器进行更多优化,因此它可以减少您的字符串 (RVO) 的副本。
回答by kizzx2
As mentioned, the std::string is copied. So even the original local variable has gone out of scope, the caller gets a copy of the std::string.
如前所述, std::string 被复制。因此,即使原始局部变量已经超出范围,调用者也会获得 std::string 的副本。
I think reading on RVOcan totally clear your confusion. In this case, it's accurately referred to as NRVO (Named RVO) but the spirit is the same.
我认为阅读RVO可以完全消除您的困惑。在这种情况下,它被准确地称为 NRVO(命名 RVO),但精神是一样的。
Bonus reading: The problem with using RVO is that it's not the most flexible thing in the world. One of the big buzzes of C++0x is rvalue referenceswhich intends to solve that problem.
奖励阅读:使用 RVO 的问题在于它不是世界上最灵活的东西。C++0x 的一大亮点是旨在解决该问题的右值引用。
回答by Martin Broadhurst
Have you tried it? The string is copied when it's returned. Well that's the official line, actually the copy is probably optimised away, but either way it's safe to use.
你试过吗?字符串在返回时被复制。好吧,这是官方路线,实际上副本可能已优化掉,但无论哪种方式都可以安全使用。
回答by Paul E.
Well, ret will have a value of mystring after MyFunc(). In case of returning the result by value a temporary object is constructed by copying the local one.
那么,在 MyFunc() 之后,ret 的值将是 mystring。在按值返回结果的情况下,通过复制本地对象来构造一个临时对象。
As for me, there are some interesting details about the topic in these sections of C++ FAQ Lite.
至于我,在C++ FAQ Lite 的这些部分中有一些关于该主题的有趣细节。
回答by Valentin Heinitz
It depends on use case. If instance should keep responsibility for string, stings should be returned by const reference. The problem is, what to do, if there is no object to return. With pointers the invalid object could be signalized using 0. Such a "null-object" could be also used with references (e.g. NullString in code snippet). Of cause better way to signal invalid return value is throwing exceptions.
这取决于用例。如果实例应负责字符串,则应通过常量引用返回字符串。问题是,如果没有对象返回,该怎么办。对于指针,可以使用 0 来表示无效对象。这样的“空对象”也可以与引用一起使用(例如代码片段中的 NullString)。当然,发出无效返回值信号的更好方法是抛出异常。
Another use case is if the responsibility for the string is transferred to the caller. In this case auto_ptr should be used. The code below shows all this use-cases.
另一个用例是将字符串的责任转移给调用者。在这种情况下,应使用 auto_ptr。下面的代码显示了所有这些用例。
#include <string>
#include <memory> //auto_ptr
#include <iostream>
using std::string;
using std::auto_ptr;
using std::cout;
using std::endl;
static const string NullString("NullString##代码##");
///// Use-Case: GETTER //////////////////
//assume, string should be found in a list
// and returned by const reference
//Variant 1: Pseudo null object
const string & getString( bool exists ) {
//string found in list
if( exists ) {
static const string str("String from list");
return str;
}
//string is NOT found in list
return NullString;
}
//Variant 2: exception
const string & getStringEx( bool available ) {
//string found in list
if( available ) {
static const string str("String from list");
return str;
}
throw 0; //no valid value to return
}
///// Use-Case: CREATER /////////////////
auto_ptr<string> createString( bool ok )
{
if( ok ){
return auto_ptr<string>(new string("A piece of big text"));
}else{
return auto_ptr<string>();
}
}
int main(){
bool ok=true, fail=false;
string str;
str = getString( ok );
cout << str << ", IsNull:"<<( str == NullString )<<endl;
str = getString( fail );
cout << str << ", IsNull:"<<( str == NullString )<<endl;
try{
str = getStringEx( ok );
cout << str <<endl;
str = getStringEx( fail );
cout << str <<endl; //line won't be reached because of ex.
}
catch (...)
{
cout << "EX: no valid value to return available\n";
}
auto_ptr<string> ptext = createString( ok );
if ( ptext.get() ){
cout << *ptext << endl;
} else {
cout << " Error, no text available"<<endl;
}
ptext = createString( fail );
if ( ptext.get() ){
cout << *ptext << endl;
} else {
cout << " Error, no text available"<<endl;
}
return 0;
}
Best regards, Valentin Heinitz
最好的问候,瓦伦丁·海尼茨