Jic*_*hao 6 c++ const pass-by-reference pass-by-value
class mystring {
friend ostream& operator<<(ostream &out, const mystring ss) {
out << ss.s;
return out;
}
private:
string s;
public:
mystring(const char ss[]) {
cout << "constructing mystring : " << ss << endl;
s = ss;
}
};
void outputStringByRef(const mystring &ss) {
cout << "outputString(const string& ) " << ss << endl;
}
void outputStringByVal(const mystring ss) {
cout << "outputString(const string ) " << ss << endl;
}
int main(void) {
outputStringByRef("string by reference");
outputStringByVal("string by value");
outputStringByRef(mystring("string by reference explict call mystring consructor"));
outputStringByVal(mystring("string by value explict call mystring constructor"));
} ///:~
Run Code Online (Sandbox Code Playgroud)
考虑到上面的例子,我们不能修改pass-by-reference变量,也不能修改pass-by-value变量.每种方法的输出都是一样的.由于这两种方法没有区别,为什么C++支持两种方法?
谢谢.
Ste*_*sop 21
两者之间存在差异.考虑以下:
#include <iostream>
#include <string>
using std::string;
string g_value;
void callback() {
g_value = "blue";
}
void ProcessStringByRef(const string &s) {
callback();
std::cout << s << "\n";
}
void ProcessStringByValue(const string s) {
callback();
std::cout << s << "\n";
}
int main() {
g_value = "red";
ProcessStringByValue(g_value);
g_value = "red";
ProcessStringByRef(g_value);
}
Run Code Online (Sandbox Code Playgroud)
输出:
red
blue
Run Code Online (Sandbox Code Playgroud)
仅仅因为引用是函数内部的const,并不意味着不能通过其他引用修改引用(一个对象具有多个引用或指向它的情况称为"别名").因此,传递const引用和传递const值之间存在不同 - 在引用的情况下,对象可能在调用之后发生更改.在值的情况下,被调用者具有私有副本,其不会改变.
由于它们可以执行不同的操作,因此C++允许您选择所需的内容.
无论哪种方式都会对绩效产生影响 - 当您通过价值时,必须制作副本,这需要付出代价.但是编译器然后知道只有你的函数可能有对该副本的任何引用,这可能允许其他优化.callback()在返回之前,ProcessStringByRef无法加载字符串的内容以进行打印.如果编译器认为这样做更快,则ProcessStringByValue可以.
通常你关心副本,而不是指令的执行顺序,因为通常副本更昂贵.通常情况下,尽可能通过引用传递非常重要的对象进行复制.但是,即使实际上没有出现混叠,通过阻止某些优化,混叠的可能性有时会对性能产生严重影响.这就是"严格别名规则"存在的原因,以及restrictC99中的关键字.
f(const string&)通过const引用获取字符串:f直接在引用传递的字符串对象上操作:不涉及复制.const但是可以防止对原始对象的修改.
f(const string)获取字符串值,这意味着f给出了原始字符串的副本.即使你丢弃const,当通过值时,f返回时对字符串的任何修改都会丢失.
我不清楚你的意思是"为什么C++支持这两种方法?".这只是适用的一般重载规则.
f(string s)通过值传递字符串s,换句话说,它创建一个副本并使用您传递的字符串的值初始化它.对副本的任何更改都不会传播到您传递给调用函数的原始字符串.在f(const string s)const中是多余的,因为你无论如何都不能改变原始值.
在f(const string& s)不是字符串是不可复制的,但你传递给它的参考.这通常在你有一个大对象时完成,因此"pass-by-value"会产生开销(这就是c ++支持这两种方法的原因).通过引用传递意味着您可以更改传递的"大"对象的值,但由于const说明符,您无法修改它.这是一种"保护".