#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;
}