繁体   English   中英

为什么按值传递局部变量有效?

[英]Why does passing local variable by value work?

# include <iostream>
# include <string>
using std::string;
using std::cout;
using std::endl;

string func() {

    string abc = "some string";
    return abc;

}

void func1(string s) {

    cout << "I got this: " << s << endl;

} 

int main() {

    func1(func());
}

这给出:

$ ./a.out 
I got this: some string

这段代码如何/为什么工作? 我想知道是因为abc超出了范围并在对func()的调用完成后立即被销毁。 所以abc的副本不能/不应该在函数func1中的变量s中可用这种理解是否正确?

返回值是从局部变量复制的,有效地创建了一个新的字符串对象。

然而,RVO(返回值优化)应该消除这一步。

尝试在调试器中单步执行您的代码。 您应该会看到为返回行调用的 std::string 复制构造函数。 确保在启用调试和关闭优化器的情况下进行编译。

您的代码本质上是在问:

“调用 func1,为了让 func1 工作,我必须接收一个字符串,我们可以通过调用该字符串上的复制构造函数来使用它。我们希望 func1 的参数来自 func 的返回值(我们知道必须是一个字符串,因为它明确定义了”。

只有在传递字符串值的 func() 的返回值上调用复制构造函数后,abc 才会超出范围。 从理论上讲,您可以编写它通过引用或常量引用传递:

void func1(string& s) {
cout << "I got this: " << s << endl;
} 

这允许 func1 通过指针直接访问内存中的字符串(如果您的代码打算这样做,还可以更改它。)

void func1(string const& s) {
cout << "I got this: " << s << endl;
} 

它提供了对来自 func() 的字符串的常量引用。 这确保您获得指向数据的指针并且您不会更改其内容。 通常通过常量引用 (const&) 传递数据是可取的,因为它非常快,并且可以防止您的代码意外更改不应该更改的数据。

如果您要在将数据传递给新函数后对其进行操作,您实际上只需要按值传递,从而节省创建另一个新容器来处理操作的资源:

void func1(string s) {
s += " some extra stuff to add to the end of the string";  //append some new data
cout << "I got this: " << s << endl;
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM