将C ++本地字符串返回给另一个函数

时间:2017-09-16 04:37:33

标签: c++ string function memory scope

这是我的困惑。我认为s1s2是类型string的函数本地对象实例,我们不应该将函数本地范围对象返回到外部。但似乎下面的代码工作,想知道为什么?

vector<string> testString(){
    vector<string> result;
    string s1 = "123";
    string s2 = "456";
    result.push_back(s1);
    result.push_back(s2);

    return result;
}

void testStringWrapper(){
    vector<string> result = testString();
    for (int i=0; i<result.size(); i++) {
        cout << result[i] << endl;
    }
}

3 个答案:

答案 0 :(得分:4)

通过引用或指针返回任何内容,按值返回 - 这是可以接受的。根据需要执行复制/移动。

vector<string> testString(){
    // Declares a vector that will be returned:
    vector<string> result;

    // Creates two local strings:
    string s1 = "123";
    string s2 = "456";

    // *Copies* the local strings into the vector *by value*:
    result.push_back(s1);
    result.push_back(s2);

    // Returns the vector *by value*.  A copy might be made, but NVRO will elide it.
    return result;
}

vector<string>包含函数本地的字符串副本。

通过字符串移动到向量中可以提高效率,而#34; pilfers&#34;来自源字符串对象的数据指针,使其处于未指定但有效的状态:

// Instead of:
// result.push_back(s1);
// result.push_back(s2);

// Move the strings:
result.emplace_back(std::move(s1));
result.emplace_back(std::move(s2));

然后没有复制,s1s2不再包含各自的值 - 向量窃取了内容。

答案 1 :(得分:1)

您正在返回值,因此他们会被复制或转移到呼叫网站。那很好。

答案 2 :(得分:0)

当你这样做时:

vector<string> testString(){
    vector<string> result;
    ...
    return result;
}

在本地范围创建向量result,但在函数超出范围之前,返回它,关键部分是函数的返回类型为vector<string>,其中< strong>副本 result并将其返回给函数的调用者,在您的情况下将其分配给全新的值:

 vector<string> result = testString();

但请勿与result范围和testString()范围内testStringWrapper()的相同名称混淆。

这两个result向量是内存中的不同对象。这与例如vector<string> foo = testString();相同。

  

我们不应该将函数局部范围对象返回到外部

在某些情况下是正确的。

通过引用返回或指针时,这适用。在这种情况下,你会有这样的事情:

// BAD PRACTICE
vector<string>& testString(){
    vector<string> result;
    ...
    return result;
}

并且一旦函数终止,您将返回对超出范围的对象的引用。因此,当您尝试在testString()之外访问它时,您将访问超出范围的内存。

此问题的典型解决方案是使用new为您的对象动态分配内存,通过引用返回它,然后自己管理内存(据说,在您调用之前,内存不会被取消分配delete就可以了。)