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


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

struct Aux {
    char* buf{ nullptr };
    int length{ 0 };
    int count{ 0 };

    int getLength() {
        if (buf != nullptr) {
            length = strlen(buf);
            return length;
        }
        return 0;
    }
};

class MyStr {
    Aux* data{ nullptr };

public:
    MyStr() {
        data = new Aux();
        cout << "  MyStr default constr.\n";
    }

    MyStr(const char* init_val) {
        data = new Aux();
        if (init_val != nullptr && *init_val != '\0') {
            data->length = strlen(init_val);
            data->buf = new char[data->length + 1];
            strcpy(data->buf, init_val);
        }
        cout << "  MyStr( char * ) constr.\n";
    }

    MyStr(const MyStr& other) {
        data = new Aux();
        data->length = other.data->length;
        if (data->length > 0) {
            data->buf = new char[data->length + 1];
            strcpy(data->buf, other.data->buf);
        }
        cout << "  MyStr copy const.\n";
    }

    ~MyStr() {
        cout << "  MyStr destr.\n";
        if (data->buf != nullptr) {
            delete[] data->buf;
            data->buf = nullptr;
        }
        if (data != nullptr) {
            delete data;
            data = nullptr;
        }
    }

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

    MyStr& operator= (const MyStr& other) {
        cout << "  MyStr::operator=\n";
        if (this != &other) {
            // Очищаем старую память
            if (data->buf != nullptr) {
                delete[] data->buf;
                data->buf = nullptr;
            }
            
            data->length = other.data->length;
            if (data->length > 0) {
                data->buf = new char[data->length + 1];
                strcpy(data->buf, other.data->buf);
            } else {
                data->buf = nullptr;
            }
        }
        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->buf[index];
    }
};

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

    // Очищаем буфер res (на всякий случай)
    if (res.data->buf != nullptr) {
        delete[] res.data->buf;
        res.data->buf = nullptr;
    }
    
    res.data->length = s1.data->length + s2.data->length;
    res.data->buf = new char[res.data->length + 1];

    if (s1.data->length > 0)
        strcpy(res.data->buf, s1.data->buf);
    if (s2.data->length > 0)
        strcat(res.data->buf, s2.data->buf);

    return res;
}

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

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

    return 0;
}