另一个 C++ 学习时刻:从函数返回字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3282608/
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
Another C++ learning moment: returning strings from functions
提问by JnBrymn
I've got some basic questions about C++. Consider the following code in which I attempt to return a string.
我有一些关于 C++ 的基本问题。考虑以下我尝试返回字符串的代码。
const std::string&
NumberHolder::getValueString() {
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
std::string valueString(valueCharArray);
return valueString;
}
I'm attempting to return a string with the value of a class member called _value. However I'm getting the warning that I'm trying to pass back a pointer to a local variable. This is of course a bad thing. If I understand C++ enough at this point, this means that the pointer I pass back will already have delete called on it by the time someone tries to use it. So I modify:
我试图返回一个字符串,该字符串包含名为 _value 的类成员的值。但是,我收到警告,提示我正在尝试将指向局部变量的指针传回。这当然是一件坏事。如果我此时对 C++ 足够了解,这意味着我传回的指针在有人尝试使用它时已经调用了 delete 。所以我修改:
const std::string&
NumberHolder::getValueString() {
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
std::string valueString = new std::string(valueCharArray);
return (*valueString);
}
This should create a pointer on the stack which will survive outside of this function. Two problems here though: 1) it doesn't compile anyway and I don't understand why (error = cannot convert from 'std::string *' to 'std::basic_string<_Elem,_Traits,_Ax>') and 2) This seems like a potential memory leak because I'm depending upon someone else to call delete on this guy. What pattern should I be using here?
这应该在堆栈上创建一个指针,该指针将在此函数之外继续存在。但是这里有两个问题:1)它无论如何都无法编译,我不明白为什么(错误 =无法从 'std::string *' 转换为 'std::basic_string<_Elem,_Traits,_Ax>')和 2 ) 这似乎是一个潜在的内存泄漏,因为我依赖其他人对这个人调用 delete 。我应该在这里使用什么模式?
回答by In silico
You're defeating the point of having a std::string
by allocating it on the heap!
你std::string
通过在堆上分配它来打败拥有 a的意义!
Just return it by value like this:
只需像这样按值返回它:
std::string NumberHolder::getValueString()
{
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
return std::string(valueCharArray);
}
Just about every compiler nowadays will do return value optimization(RVO)on the return statement, so no copies should be made. Consider the following:
现在几乎每个编译器都会对 return 语句进行返回值优化(RVO),因此不应进行复制。考虑以下:
NumberHolder holder;
// ...
std::string returnedString = holder.getValueString();
With RVO, the compiler will generate the code for the above implementation of NumberHolder::getValueString()
such that std::string
is constructed at the location of returnedString
, so no copies are needed.
使用 RVO,编译器将为在 的位置构造的NumberHolder::getValueString()
此类的上述实现生成代码,因此不需要副本。std::string
returnedString
回答by James McNellis
You are getting this warning because you are returning a referenceto the local string, not a copy of the local string. Once the function returns, the local string is destroyed and the reference that you returned is invalid. Thus, you need to return the string by value, not by reference:
您收到此警告是因为您返回的是对本地字符串的引用,而不是本地字符串的副本。函数返回后,本地字符串将被销毁,并且您返回的引用无效。因此,您需要按值返回字符串,而不是按引用:
std::string NumberHolder::getValueString()
回答by DumbCoder
Your 1st attempt is correct if you return a temp variable but bind it in a const reference.
如果您返回一个临时变量但将它绑定在一个常量引用中,那么您的第一次尝试是正确的。
const std::string NumberHolder::getValueString(){}
const std::string& val = NumberHolder::getValueString();
const. But your second attempt is dangerous, depending on somebody else to delete.
常量。但是您的第二次尝试很危险,这取决于要删除的其他人。
回答by Amber
std::string *valueString = new std::string(valueCharArray);
You'd need to create a pointer variable to hold the result from new
, since it returns the pointer. However, the ideal solution would really be just to return by value:
您需要创建一个指针变量来保存来自 的结果new
,因为它返回指针。但是,理想的解决方案实际上只是按值返回:
std::string NumberHolder::getValueString() {
...
return std::string(valueCharArray);
}