问题描述
今天遇到一个关于C++引用的错误,说实话以前确实一直没注意到过引用还有这个规则
1>------ 已启动生成: 项目: OpenGL, 配置: Debug Win32 ------
1>Game.cpp
1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): error C2664: “void SpriteRenderer::DrawSprite(Texture2D &,glm::vec2,glm::vec2,GLfloat,glm::vec3)”: 无法将参数 1 从“Texture2D”转换为“Texture2D &”
1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): note: 非常量引用只能绑定到左值
1>已完成生成项目“OpenGL.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
先解释左值和右值的区别:
- 从字面意思看,左右值就是在“=”两端的变量或表达式(以前我一直是这样理解的/手动狗头),但其实不是这样的。
- 左值(Location Value):并不是left_value,指的是可以寻址。指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储,那么这个表达式就可以作为一个左值。
- 右值(Read Value):也就是可读。指的是引用了一个存储在某个内存地址里的“数据”。
例子:
void func(int &a)
{
cout << a;
}
void main()
{
double i = 4;
func(i);//这里进行了强制类型转换,会产生一个临时变量}
上面的写法是不合法的,会报错“非常量的引用只能绑定到左值”,按照正常理解 i 其实是一个左值,但是由于定义的 i 和func函数需要的参数并不是相同类型,这里实际上经过了一次强制类型转换,并且生成了一个临时变量(而临时变量都是常量,不能作为左值,只能由const引用,不能改变值),所以这里非const的引用会报错
这里解决方式有两种
让实参和形参类型相同,不必进行强制类型转换
void func(int &a) { cout << a; } void main() { int i = 4; //修改i的类型 func(i); }
使用右值引用
void func(const int &a)//右值引用 { cout << a; } void main() { double i = 4; func(i); }
另外,右值引用可以延长临时变量的生命周期,比如这个例子:
int func(int a){
return a += 10; //函数返回值也是一个临时变量
}
void main() { int i = 10;
const int &b = func(i); //变量a是对函数返回值(临时变量)的引用,因此函数返回值不会在此时立即销毁,而是一直延续到整个程序结束
cout<<b;
}