Вызывается конструктор, а не оператор присвоения

class String
{
    size_t len;
    char* buffer;
public:
    String(const char* str)
    {
        len = strlen(str);
        buffer = new char[len + 1];
        memcpy(buffer, str, len + 1);

        std::cout << "Call CTR " << str << endl;


    }
    friend std::ostream& operator<< (std::ostream& stream, const String& str);
    ~String()
    {
        delete[] buffer;
    }

    String& operator= (const String& str)
    {
        delete[] buffer;
        if (this == &str)
        {
        }
        this->len = str.len;
        buffer = new char[len + 1];
        memcpy(buffer, str.buffer, len + 1);
        return *this;

        std::cout << "Call COPY " << str << endl;
    }

    char& operator[] (unsigned int index)
    {
        return buffer[index];
    }

    String(const String& str) 
        :
        len(str.len)
    {
        buffer = new char[len + 1];
        memcpy(buffer, str.buffer, len + 1);
    }

};

std::ostream& operator<< (std::ostream& stream, const String& str)
{
    stream << str.buffer;
    return stream;
}

int main(int argc, char* argv[])
{
    
    String str = "string";
    String str2 = str;

    str = "str2";
    return 0;
}

При вызове str = "str2"; вызывается конструктор String(const char* str), хотя долен String& operator= (const String& str)

Разве не так? Почему вызывается конструктор повторно?


Ответы (1 шт):

Автор решения: AlexGlebe

Оператор присваивания требует на вход объект вашего класса, а вы ему подсовываете строку.

Язык C++ решает эту проблему, автоматически создавая временный объект, чтобы присваивание получилось и после успешного выполнения этот объект удаляет.

str = "str2";

// создаёт временный объект вызывая конструктор
// и выполняет оператор присваивания
str = String { "str2" } ;
// удаляёт временный объект вызывая деструктор

Ваша запись str = "str2"; идентична str = String { "str2" } ; просто первая короче, а вторая нагляднее.

Чтобы не создавался новый временный объект обычно пишут ещё один оператор присваивания, но с аргументом простой строки.

String& operator= (const char* str){
    delete []buffer ; 
    len = strlen(str);
    buffer = new char[len + 1];
    memcpy(buffer, str, len + 1);
    return * this ;
}
→ Ссылка