C++学习——引用变量中易出现的错误

        在C++学习中容易出现变量引用不恰当导致编译错误,先来看一段代码:

#include <bits/stdc++.h>
using namespace std;
void printMessage(string& message) {
    cout << message << endl; }
int main() {
    // 常规字符串赋值给变量
    string msg = "Hello, World!";
    printMessage(msg);//输出正确
    // 临时对象(字符串字面值)
    printMessage("Hello, World!");
	//出现错误:[Error] cannot bind non-const lvalue reference
    //  of type 'std::string&'  to an rvalue of type 'std::string' 
    return 0;
}

上面的第二个引用构造函数会出现错误,意思是一个非 const 的左值引用绑定到一个右值的表达式或对象上,这里重点谈谈左值与右值的引用及注意事项。

左值引用与右值引用

       左值(lvalue)和右值(rvalue)是C++11 及之后的版本中表达式分类的术语,它们描述了表达式在内存中的位置或状态。

       左值代表“locator value”,通常指的是具有明确存储位置(即内存地址)的对象。左值可以出现在赋值语句的左侧,因为它们可以被定位,并且它们的值可以被修改。例如,变量、数组元素和通过解引用得到的指针等都是左值。

       右值代表“pure value”,通常指的是临时对象,即没有固定存储位置的值。右值不能出现在赋值语句的左侧,因为它们没有内存地址,不能被修改。字面量、临时对象和表达式的结果等通常都是右值。

     认识了左值与右值,再来看看它们的引用:    

  •  非const左值引用(如 int&、int*)必须绑定到一个左值上,因为左值可以被修改,而引用本质上是对其绑定对象的别名,可以通过引用来修改对象的值。
    int a = 100;     // a 是左值,因为它有明确的内存地址,并且可以被赋值
    int* p = &a;    // p 是左值,因为它指向一个有明确内存地址的对象
    *p = 200;       // 通过指针解引用p(即a),我们可以修改a的值
  •  右值引用(如 int&&)则可以绑定到右值上,从C++11开始,它们被用于实现移动语义和完美转发等特性,允许对象资源的转移而不是复制。
    int a = 100;    // 100 是右值,它是一个字面量,没有内存地址
    int b= a + 1;   // a + 1 的结果是右值,因为它是一个临时计算出来的值
    
    void fuc(int&& i) {
        i = 100;   // 函数内部可以修改 i 的值,因为它是右值引用
    }
  •  const左值引用(如 const int&),即常量引用。可以绑定到左值或右值上,但对常量引用的任何修改都是不允许的,一旦赋值初始化后就不能修改,只能读取。由于这个特性,在函数参数中使用const左值引用可以提高效率,因为它允许传递临时对象而无需复制,同时保证函数不会修改传入的值。这通常用于优化性能,特别是在处理大型对象或资源密集型对象时。
    int a = 10;
    const int& b = a;   // b 是一个const左值引用,绑定到a
    const int& c = 20;   // c 是一个const左值引用,可以赋值一个右值
    a=c; // 正确:可以通过const引用读取所引用的值,运行后同时会改变b的值
    b = 30; // 错误:不能修改const引用的值

    通过分析,文章开始的构造函数据修改为如下,变为常量引用即可。

    void printMessage(const string& message) {
        cout << message << endl;
    }
    int main() {
        // 常规字符串
        string msg = "Hello, World!";
        printMessage(msg);//输出正确
    
        // 临时对象(字符串字面值)
        printMessage("Hello, World!");//输出正确

    总之,我们需要看懂编译错误提示,确保引用的类型与要绑定的对象的类型兼容或匹配。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值