C++中把临时实例赋给引用的问题

问题现象描述

临时实例赋值给非常量引用,会警告:warning C4239: 使用了非标准扩展:“参数”,原因是:“非常量引用只能绑定到左值”。

例如下面例子:

struct B {
	B(int ti) {}
};

struct A {
	A() {};
	A(B &other) {  }
};


void func(void) {
	A cobj(B(123)); // 会警告:非常量引用只能绑定到左值
}

原理分析

引用的本质是某对象的影子副本,操作引用就相当于操作某对象本身,引用实现本质就是一个指针,这个指针需要指向一个实在能拿到地址的对象,否则就没有意义。

例如:int &i = 8; 如果执行 i=2;,那根本不知道去修改谁,因为“8”不是可以指向的变量实例,也就是此时的引用“i”是没意义的。

不仅如此,如果非常量刑引用和临时变量捆绑,编译器也会警告,因为程序后续的操作,实际修改的是临时变量,编译器认为如此操作是有风险或者不符合程序员本意需要。

回到上面提的例子中的“A cobj(B(123))”,此时的“B(123)”就是一个临时变量,它要被当作“B &”调用A的构造函数,相当于先建立一个 把“B(123)”临时变量赋给"B&"变量,所以编译器就发出警告。

如果程序员了解这个细节,其实可以不管这个警告,只需关闭这个警告就行。

修改办法

修改办法很多,可以改为不赋值给引用,或者额外定义个变量来赋给引用就行。

例如上面例子修改:

void func(void) {
    B tmpb(123);
    A cobj(tmpb); 
}

或者这样(程序员务必了解如此是否符合自己的业务需要):

struct B {
	B(int ti) {}
};

struct A {
	A() {};
	A(B other) {  } // 构造时候不用引用
};


void func(void) {
	A cobj(B(123));
}


 

本文结束。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章