Загрузка данных


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

// НОВАЯ СТРУКТУРА (вместо прямых полей в MyStr)
struct Aux {
    char* buff{ nullptr };    // указатель на строку
    int length{ 0 };          // длина строки
    int count{ 1 };           // счетчик ссылок
};

class MyStr {
    Aux* data{ nullptr };     // вместо int length и char* buff
public:

    MyStr() : data(new Aux{nullptr, 0, 1})  // пустая строка
    {
        cout << "  MyStr default constr.\n";
    }

    MyStr(const char* init_val)
    {
        if (init_val != nullptr && *init_val != '\0')
        {
            data = new Aux;
            data->length = strlen(init_val);
            data->buff = new char[data->length + 1];
            strcpy(data->buff, init_val);
            data->count = 1;
        }
        else
        {
            data = new Aux{nullptr, 0, 1};  // пустая строка
        }
        cout << "  MyStr( char * ) constr.\n";
    }

    MyStr(const MyStr& other) : data(other.data)
    {
        cout << "  MyStr copy const.\n";
        data->count++;  // увеличиваем счетчик ссылок
    }

    ~MyStr()
    {
        cout << "  MyStr destr.\n";
        if (--(data->count) == 0) {  // уменьшаем и проверяем
            delete[] data->buff;
            delete data;
        }
    }

    int size() { return data->length; }

    MyStr& operator= (const MyStr& other)
    {
        cout << "  MyStr::operator=\n";
        if (this != &other) {
            // уменьшаем счетчик старых данных
            if (--(data->count) == 0) {
                delete[] data->buff;
                delete data;
            }
            // делим новые данные
            data = other.data;
            data->count++;
        }
        return *this;
    }

    friend MyStr operator+(const MyStr& s1, const MyStr& s2);
    friend ostream& operator<< (ostream&, const MyStr&);

    char& operator[] (int index)
    {
        if (index < 0 || index > data->length) {
            cerr << "Invalid index in MyStr::operator[]. Aborting...\n";
            exit(-1);
        }
        return data->buff[index];
    }
};

MyStr operator+(const MyStr& s1, const MyStr& s2)
{
    MyStr res;
    if (s1.data->length == 0 && s2.data->length == 0)
        return res;

    // удаляем старые данные res (пустую строку)
    delete[] res.data->buff;
    delete res.data;
    
    // создаем новые
    res.data = new Aux;
    res.data->length = s1.data->length + s2.data->length;
    res.data->buff = new char[res.data->length + 1];
    res.data->count = 1;
    
    if (s1.data->length != 0)
        strcpy(res.data->buff, s1.data->buff);
    if (s2.data->length != 0)
        strcat(res.data->buff, s2.data->buff);

    return res;
}

ostream& operator<< (ostream& os, const MyStr& s) {
    for (int i = 0; i < s.data->length; i++)  
        os.put(s.data->buff[i]);
    return os;
}

int main() {
    MyStr a = "Hello ";
    MyStr b = "World!";
    MyStr c = a;
    c = a + b;
    cout << c << endl;
    return 0;
}