简体   繁体   中英

Copy constructor and const

Here is the code i'm having problem with

class MyString {
    char* str;
public:
    MyString(const char* _str) : str(_str) {}
}

This is the error message from the compiler

error: invalid conversion from 'const char*' to 'char*' [-fpermissive]

Is this because str is char* and _str is const char* ?

Should the copy( I mean str(_str) ) be the exact same type (REGARDING const )?

How could I modify this code into reasonable code? I want to keep MyString(const char* _str) as const char* .

Short answer: yes.

Longs answer: const char* str is a pointer to a region in memory that contains a c string. By marking it const you are saying that it may not be changed. You are attempting to create a new pointer to the same memory region, but this new pointer says that region may be changed, which the compiler complains about (since the original says that this is not allowed).

Note that you are currently not copying the contents to the string (which I suspect you want), but the pointer to the string. To actually copy the string you must first allocate memory and then copy the contents. Or just use a std::string instead, which manages all this for you.

Yes, you cannot assign a const char* pointer (a pointer-to-const) to a char* pointer (a pointer-to-non-const), they are not compatible.

If you don't mind your class pointing to the original character data as-is, then you can make the str member be a pointer-to-const:

class MyString {
    const char* str;
public:
    MyString(const char* _str) : str(_str) {}
};

You will just have to make sure the original character data outlives your MyString object.

This is likely not what you want. The other option is to make your class copy the character data into itself:

class MyString {
    char* str = nullptr;
public:
    MyString(const char* _str) {
        if (_str) {
            str = new char[strlen(_str) + 1];
            strcpy(str, _str);
        }
    }
    ...
};

Just be sure to follow the Rule of 3/5/0 to manage that copy correctly. That means implementing a destructor to free the copy, and a copy constructor and copy assignment operator to make copies of the data, and a move constructor and move assignment operator to move the data around:

class MyString {
    char* str = nullptr;
public:
    MyString() = default;

    MyString(const char* _str) {
        if (_str) {
            str = new char[strlen(_str) + 1];
            strcpy(str, _str);
        }
    }

    MyString(const MyString &src) : MyString(src.str) { }

    MyString(MyString &&src) {
        str = src.str;
        src.str = nullptr;
    }

    ~MyString() {
        delete[] str;
    }

    MyString& operator=(MyString rhs) {
        MyString tmp(std::move(rhs));
        std::swap(src, tmp.src);
        return *this;
    }
};

A better solution is to use std::string instead, which handles all of these details for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM