为什么对字符串参数的const引用可以采用字符串文字?像"hello"
这样的字符串文字不是变量,为什么这段代码有效?
class CVector {
public:
int x, y;
CVector() {};
~CVector() { delete ptr; }
string* ptr;
void doSomething(const string& str) { ptr = new string(str); }
void print() { cout << "\n" << *ptr; }
};
int main()
{
result.doSomething("asdas");
result.print();
return 0;
}
首先,我认为引用作为参数用于避免复制过程并直接访问作为参数的变量(尽管我仍然可以正确)。但字符串文字“asdas”不是变量,为什么参数将字符串文字作为参数?我的意思是因为参数str
是一个引用,它将成为该实体的别名,对吧?如果是这样,文字是否只是变量?
参数列表不应该由string& str
而不是const引用组成,因此文字将用于构造str
吗?
并且只要引用处于活动状态,并不是const引用使引用的实体保持活动状态?如果是这样,你为什么要这样做呢?
答案 0 :(得分:6)
当你这样做时
result.doSomething("asdas");
编译器会查看您是否有doSomething(const char[]);
并且一无所获。由于没有合适的函数,它会尝试找到一个重载,它可以从const char[]
构造一些东西并找到doSomething(const string& str)
。由于允许编译器进行一次用户定义的转换,因此它从字符串文字构造一个临时的std::string
,并通过对const的引用将该临时函数传递给函数。
参数列表不应该包含字符串&amp; str而不是const引用,以便文本将用于构造str?
不,这仅适用于对const的引用,并且不适用于常规引用,因为常规引用无法绑定到临时引用。
并且,只要引用处于活动状态,并且没有const引用使引用的实体保持活动状态?如果是这样,你为什么要这样做呢?
对const的引用只有在它是函数本地对象时才会延长对象的生命周期。在函数范围内,对象将处于活动状态,因为调用该函数的表达式尚未结束,但是如果您尝试在类中保留对std::string
的引用,则该引用将无效。
有效地将代码翻译成
int main()
{
CVector result
{
std::string temp = "asdas";
result.doSomething(temp);
}
result.print();
return 0;
}
答案 1 :(得分:4)
字符串文字,如“hello”,不是变量
术语“变量”的定义非常模糊,并没有真正支持任何具体的概念。
表达式"hello"
表示具有您无法修改的静态存储持续时间的对象。与任何其他表达式一样,它可能用于初始化其他一些对象。在这种情况下,您使用表达式(在其衰减到std::string
之后)初始化const char*
。
你缺少的是“中间步骤”,即从该文字构造一个临时std::string
,其生命周期随后通过绑定扩展到ref-to - const
。< / p>
所以,ish:
const std::string temp{"Hello world"}; // the compiler creates this transparently
const std::string& ref = temp; // this is yours, and it extends temp's life
了解更多信息,了解隐式转化。
答案 2 :(得分:1)
std::string
有一个隐式的const char *
转换构造函数。
允许编译器进行一次隐式转换以使类型匹配,因此它使用所述ctor将const char *
转换为std::string
临时转换,并且&#39;从那里顺利航行,因为const&
(const lvalue references)被允许绑定到临时工(并延长他们的生命周期)。