我对我教科书中的一个例子感到有点困惑。创建字符串时,会将其创建为类型字符串。但是,当相同的字符串传递给函数时,函数参数是const字符串而不是字符串。
以下是代码的一部分:
int main()
{
string str;
cout << "blah blah..";
getline(cin, str);
if (is_pal(str))
.
.
.
}
bool is_pal(const string& s)
{
.
.
.
}
为什么函数参数是const string&amp; s而不仅仅是字符串&amp; S'我翻过教科书,但似乎无法找到任何解释= / 感谢。
答案 0 :(得分:7)
复制可能很昂贵的对象,例如std::string
,通常在C ++中通过const lvalue引用传递。这是一个非常普遍的习语;你会到处看到它。 const lvalue引用可以绑定到lvalues和rvalues而不进行任何复制,因此这是将字符串传递给不会修改它们的函数的有效方法。
答案 1 :(得分:2)
当函数在其参数上使用onkeyup
时,通常意味着函数不会改变参数。
在编写自己的函数时,应确定函数是否打算修改参数,并相应地使用或不使用const
。
同样,当您使用其他人编写的函数时,请注意该函数是否打算修改您的对象。如果函数接受非const
引用,则会使您知道。
const
答案 2 :(得分:2)
RE
“为什么函数参数
const string& s
而不只是string& s
?
一个主要原因是后者不能绑定到字符串文字或普通函数结果或字符串运算符的结果,例如+
,称为“rvalue”。
至少在标准C ++中,但Visual C ++允许将其作为不幸的语言扩展。
另一个原因通常是该函数的作者认为当它承诺不修改其参数时它可能更有用。或者至少,这样可以更容易推理使用它的代码。
示例:
// To see the problem also with Visual C++, use that compiler's /Za option.
#include <iostream>
#include <string>
using namespace std;
void goodwrite( const string& s ) { cout << s << '\n'; }
void badwrite( string& s ) { cout << s << '\n'; }
auto main() -> int
{
// Good:
goodwrite( "The answer is " + to_string( 6*7 ) + "." );
//! Uh oh, doesn't compile with standard C++:
badwrite( "The answer is " + to_string( 6*7 ) + "." );
}
答案 3 :(得分:0)
传递const
引用意味着该函数会将参数视为常量,并且不会以任何方式对其进行修改。这允许使用const值调用此函数 - 显式定义为const
s或隐式常量(如字符串文字)。
答案 4 :(得分:0)
你可以在没有&#34; const&#34;关键字。
通常最好的做法是使用&#34; const&#34;参数的关键字,如果您的函数没有修改它。因此,如果您尝试修改参数,则会出错,否则会出错。
它只是最好的编码实践,如果函数没有修改参数,我建议你也这样做。
答案 5 :(得分:0)
TL; DR :确保在功能中未修改对象并保存一个复制操作。
可能只为const
个对象调用const
个方法,并且这些方法无法改变对象的状态:
class A {
int i = 10;
mutable int j = 10; // Explicitly allowed to change even for const objects
public:
void f() { ++i; } // OK: non-const function changes object
void g() const { ++i; } // Error: const function changes object
int h() const { return i; } // OK: const function doesn't change object
int s() const { return ++j; } // OK: const function changes mutable field
};
void foo(const A& a) {
a.f(); // Error: only const methods are allowed
a.g(); a.h(); a.j(); // OK
}
正如您所看到的,没有干净的方法来修改函数i
中的字段foo
,但您可以阅读A
字段h()
和s()
方法。
您还可以通过将副本传递给它来确保您的本地对象不被被调用者函数修改:
void foo(A a);
bool is_pal(std::string s);
但是复制可能很昂贵,所以你必须通过引用传递它:
void foo(A& a);
bool is_pal(std::string& s);
要确保对象在调用函数之前具有相同的状态,您必须向其添加const
限定符。这个成语在 Scott Meyers的书,Effective C ++,Third Edition ,&#34; Item 20:Prefer by-reference-to-const to pass-by-value中进行了解释。&#34 ;