search

Home  >  Q&A  >  body text

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

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

怪我咯怪我咯2804 days ago605

reply all(3)I'll reply

  • PHP中文网

    PHP中文网2017-04-17 13:49:59

    Because if you define it this way, the string type of rvalue cannot successfully match the constructor. const string& can reference both rvalue and lvalue, while string& can only reference lvalue.
    Also, as mentioned above, in order to avoid type conflicts with the namespace in std string, it is best to put it in your own namespace or change the name. .

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:49:59

    You are using something confusing here. The custom class is called string, and the string in the standard STL is also a string. There is a conflict. When compiling the matching constructor, it thinks that the type string&tmp is the string in the matching STL. Rather than your own custom one.

    #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类型的

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:49:59

    The problem is here

    string str = "hello";

    If you replace it with string str("hello"); there should be no problem.

    Because = is used here, there is no suitable constructor matched here.

    string str = "hello"; can be seen as string str(string("hello")).

    string("hello") can correctly match the string(const char*) constructor, which returns a temporary string object, which is an rvalue. But this rvalue does not know how to convert to string& or const char* type to construct str.

    Error reportinginvalid initialization of non-const reference of type 'string&' from an rvalue of type 'string' is for this reason.

    Then let’s talk about this string str(string("hello")). Don’t think that this will be constructed twice. In fact, it won’t. Because string("hello") has already constructed the string object here, it is just str and will not be constructed multiple times.

    The occurrence of this problem depends on what compiler you are using. If you try using VS2013, there will be no such problem.

    reply
    0
  • Cancelreply