c++ - 自定义类里面的拷贝构造函数问题

浏览:27日期:2023-05-03

问题描述

自定义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限定,就可以成功编译运行,请问这是为什么?

问题解答

回答1:

因为你这么定义的话,右值的string类型就无法成功匹配到构造函数了,const string&能同时引用右值和左值,而string&只能引用左值。还有像楼上说的,为了避免和namespace std中的string类型冲突,最好放到你自己的namespace中或者改名。。

回答2:

你这里用混了吧,自定义的类叫string,标准的STL里的字符串也是string,冲突了,编译在匹配构造函数时,认为string& tmp 这个类型是匹配的STL里的string,而非你自定义的。

#include <iostream>#include <math.h>using namespace std;class MyString{public: MyString(const char *tmp){cout << 'MyString(const char *tmp) called'<<endl; }};int main(){ MyString s = 'hello '; return 0;}在拷贝构造里,参数作为right-value被传递进来,是属于const类型的回答3:

问题在这里

string str = 'hello';

你把它换成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试试,就没有这样的问题了。

相关文章: