为什么对字符串参数的const引用可以采用字符串文字?

时间:2017-05-22 19:11:22

标签: c++ string reference string-literals const-reference

为什么对字符串参数的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引用使引用的实体保持活动状态?如果是这样,你为什么要这样做呢?

3 个答案:

答案 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)被允许绑定到临时工(并延长他们的生命周期)。