#include <iostream>

namespace java { namespace lang {
class Object;
class String;

class Object 
{
public:
	Object() { }
	virtual String toString() const ;
};
class String : public Object {
	friend void println(String& str);
protected:
	char *str;
	unsigned long len;
public:
	String() { str = new char[1]; *str = '\0'; len = 0; } 
	String(unsigned long val);
	String(char* s);
	String(const String& another);
	~String() { delete [] str; }
	String toString() const;
	unsigned long length() const;
	String operator + (const String& another) const;
	String& operator = (const String& ref);
};

String Object::toString() const {
	return String("Object:") + String((unsigned long)this);
}

String::String(unsigned long val) {
	char temp[33];
	unsigned long digit = 0;
	do {
		temp[digit] = (char)(val % 10);
		val /= 10;
		digit++;
	} while (val > 0);
	str = new char[digit + 1];
	str[digit] = '\0';
	len = digit;
	for (unsigned long i = 0; i < digit; ++i) {
		str[i] = temp[digit - i - 1] + '0';
	}
}

String::String(char *s) {
	len = 0;
	char *t;
	for (t = s; *t != '\0'; ++t) {
		len++;
	}
	str = new char[len + 1];
	for (unsigned long i = 0; i < len; ++i) {
		str[i] = s[i];
	}
	str[len] = '\0';
}

String::String(const String& another) {
	len = another.len;
	str = new char[len + 1];
	for (unsigned long i = 0; i < len; ++i) {
		str[i] = another.str[i];
	}
	str[len] = '\0';
}

String String::toString() const { return *this; }
unsigned long String::length() const { return len; }

String String::operator + (const String& another) const {
	unsigned long sum = len + another.len;
	char *tempstr = new char[sum + 1];
	for (unsigned long i = 0; i < len; ++i) {
		tempstr[i] = str[i];
	}
	for (unsigned long i = 0; i < another.len; ++i) {
		tempstr[len + i] = another.str[i];
	}
	tempstr[sum] = '\0';
	String temp;
	delete [] temp.str;
	temp.str = tempstr;
	temp.len = sum;
	return temp;
}

String& String::operator = (const String& ref) {
	delete [] str;
	len = ref.len;
	str = new char[len + 1];
	for (unsigned long i = 0; i < len; i++) {
		str[i] = ref.str[i];
	}
	str[len] = '\0';
	return *this;
}

void println(String& str) {
	using namespace std;
	cout << str.str << endl;
}

}}

int main() {
	using namespace java::lang;
	Object obj;
	String str(obj.toString());
	String hoge("Hoge");
	String h2(hoge + str);
	println(str);
	println(hoge);
	println(h2);
	return 0;
}