#include <algorithm>
#include <iostream>
#include <cstring>

class String
{
	int length_;
	char * data_;
	
public:
	String()
		: length_ { 0 }
		, data_ { nullptr }
	{
	}
	
	String(char const * str, int len = 0)
		: length_ { static_cast<int>(len ? len : strlen(str)) }
		, data_ { new char[length_ + 1] }
	{
		strcpy(data_, str);
	}
	
	String(String const & orig)
		: length_ { orig.length_ }
		, data_ { new char[length_ + 1] }
	{
		strcpy(data_, orig.data_);
	}
	
	String & operator = (String const & orig)
	{
		String tmp { orig };
		swap(tmp);
		return *this;
	}
	
	~String()
	{
		delete[] data_;
	}
	
	void swap(String & other)
	{
		if (this == &other) return;
		std::swap(length_, other.length_);
		std::swap(data_, other.data_);
	}
	
	String operator + (String const & rhs) const
	{
		String result;
		result.length_ = length_ + rhs.length_ + 1;
		result.data_ = new char[result.length_];
		strcpy(result.data_, data_);
		strcat(result.data_, rhs.data_);
		return result;
	}
	
	char const * c_str() const
	{
		return data_;
	}
};

int main()
{
	String foo { "foo" };
	String bar { "bar" };
	std::cout << (foo + bar).c_str() << std::endl;
	return 0;
}
