自定义string类里面拷贝构造函数代码:
string(const char* tmp) : str(new char[strlen(tmp) + 1])
{
std::cout << "call2" << std::endl;
strcpy(str, tmp);
}
string(string& tmp) : str(new char[strlen(tmp.str) + 1])
{
std::cout << "call3" << std::endl;
strcpy(str, tmp.str);
}
在main函数里面调用
string str = "hello";
报错提示:
error: invalid initialization of non-const reference of type 'string&' from an rvalue of type 'string'
note: initializing argument 1 of 'string::string(string&)'
string(string& tmp) : str(new char[strlen(tmp.str) + 1])
^
string str = "hello";
after user-defined conversion: string::string(const char*)
string(const char* tmp) : str(new char[strlen(tmp) + 1])
^
我在那个string(string& tmp)的参数前面加上一个const限定,就可以成功编译运行,请问这是为什么?
因為你這麼定義的話,右值的
string
型別就無法成功配對到建構子了,const string&
能同時引用右值和左值,而string&
只能引用左值。還有像樓上說的,為了避免和
namespace
std
中的string
類型衝突,最好放到你自己的namespace
中或改名。 。你這裡用混了吧,自訂的類別叫string,標準的STL裡的字串也是string,衝突了,編譯在匹配構造函數時,認為string& tmp 這個類型是匹配的STL裡的string,而非你自訂的。
問題在這裡
你把它換成
string str("hello");
應該就沒問題了。因為這裡使用了
=
,所以這裡沒有符合上一個合適的建構子。string str = "hello";
可以看做是string str(string("hello"))
。string("hello")
可以正確的匹配上string(const char*)
這個建構函數,其傳回一個臨時的string對象,是一個右值。但是這個右值不知道如何轉換成string&
或const char*
型別去構造str
。報錯
invalid initialization of non-const reference of type 'string&' from an rvalue of type 'string'
就是因為這個原因。然後再說這個
string str(string("hello"))
,千萬不要以為這樣會構造兩次,其實是不會的。因為string("hello")
這裡就已經把string
物件建構出來了,它就是str
,不會進行多次構造。這個問題的出現,看你用的是什麼編譯器。你用VS2013試試,就沒有這樣的問題了。