混淆参考和函数c ++

时间:2014-06-01 11:13:21

标签: c++

如果我有功能参考

string& Basic_Functions::printval(std::string &str){
  return str;
}

然后我在主

中调用它
 string  sample = "This is a sample";
 cout << sample<< endl;

printval函数是指什么?

我尝试修改了这个功能并使其像这样

string Basic_Functions::printval2(std::string &str){
  return str;
}

string& Basic_Functions::printval3(std::string str){
  return str;
}

在我的主要

string i2 = printval2(sample) = "hehe"; 

cout << i2 << endl;

string i3 = printval3(sample) = "huhuh";
cout << i3 << endl;

功能printval2易于理解。我无法理解的是printval()和printval3()。

在我正在阅读的书中,参考样本如下:

string hey = "hello"; string &woah = hey // woah is a reference to
                                         // hey. meaning it is bound to hey.

但如果你说

string i3 = printval(sample) = "huhuh"; //?

我在这里引用了什么?什么是printval()绑定到?

1 个答案:

答案 0 :(得分:1)

好的,一堆问题。从顶部:

string& Basic_Functions::printval(std::string& str) {
    return str;
}

这是不是一个函数引用,它是一个函数的定义,它引用std::string并返回对string的引用(我假设你的意思std::string而不是自定义类?)。此函数将返回传递给它的std::string的相同实例,例如

std::string s1 = "Sample string";
std::string s2 = Basic_Functions::printval(s1); // Equal to "std::string s2 = s1";

下一步:

std::string sample = "This is a sample";
std::cout << sample << std::endl;

这使用<<运算符将std::string对象sample输出到标准输出流std::cout。它与先前定义的函数printval无关。

在以下函数定义printval2printval3中,您已将返回类型更改为按值返回(返回副本),各自更改了参数类型以按值获取(参数被复制)。由于第一个功能的目的不明确,似乎有点无用,第二个和第三个版本也没有多大意义。

接下来我们发现了一些非常奇怪的东西

string i2 = printval2(sample) = "hehe";

printval2按值返回时,它等于:

string i2 = (string(sample) = "hehe");

这将使用sample创建一个临时文件并为其分配"hehe",然后它将使用临时文件初始化i2。这是非常不必要的工作,因为您使用简单的string i2 = "hehe"获得相同的效果。

第三个变体printval3引入了未定义的行为,因为它通过引用返回一个局部变量。

string& Basic_Functions::printval3(std::string str) { // Argument is copy constructed.
    return str; // Returning a reference to something that will soon be destructed.
} // All local variables are destructed here.

E.g。

const std::string& sref = printval3(sample); // Store reference.
cout << sref << endl;                        // UB! sref points to deallocated data.

最后

string i3 = printval(sample) = "huhuh"; //?

这等于

string i3 = (sample = "huhuh");

printval返回对sample的引用,然后将其分配给"huhuh",最后使用i3初始化sample。这与做

基本相同
sample = "huhuh";
string i3 = sample;