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));
}


 

本文結束。

 

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