

#include <iostream>
using namespace std;

class Str {

	char* s;
public:
	Str() {
		s = nullptr;
	}
	~Str() { //Destructor
		cout << "destroying" << endl;
		clear();
	}
	
	Str(const Str& str) {// Copy constructor
		s = 0;
		assign(str.s);
	}

	Str(const char*other) {
		s = 0;
		assign(other);
	}

	Str(Str&& other) noexcept
		: s(other.s)
	{
		other.s = nullptr;
	}

	Str& operator=(const char* str)
	{
		assign(str);
		return *this;
	}

	Str& operator=(const Str& str)
	{
		assign(str.s);
		return *this;
	}

	Str& operator=(Str&& str)
	{
		std::swap(s, str.s);
		return *this;
	}

	Str operator+(const Str& b) {
		Str res;
		if (!s || !b.s) return res;

		size_t buf = length() + b.length() + 1;
		res.s = new char[buf];

		char* o = res.s;
		if(s)
		for (char* i = s; *i; i++,o++)
		{
			*o = *i;
		}
		if(b.s) for (char* i = b.s; *i; i++, o++)
		{
			*o = *i;
		}

		*o = 0;

		return (res);
	}

	char& operator[](size_t index)
	{
		return s[index];
	}

	const char& operator[](size_t index) const
	{
		return s[index];
	}

	size_t length() const {
		size_t length = 0;
		if (!s) return 0;

		for (; s[length]; ++length);

		return length;
	}

	void clear()
	{
		if (s) delete s;
		s = nullptr;
	}

	void assign(const char* text)
	{
		cout << "assigning" << endl;
		clear();
		if (!text)
		{
			return;
		}

		size_t length;

		for (length=0; text[length]; ++length);

		s = new char[length+1] {0};

		for (size_t i = 0; i < length; ++i)
			s[i] = text[i];
	}

	const char* buffer() const {
		return s;
	}

};

ostream& operator<<(ostream& o, const Str& str) {
	return o << str.buffer();
}

int main()
{
	Str a, b;
	a = "first";
	b = "second";
	cout << a << endl;
	cout << a + Str("asd") + Str("zxc") + b << endl;
}
