#include <iostream>
using namespace std;

class Foo
{
	int number;
public:
	Foo (int number) {
		this->number = number;
	}
	
	~Foo() {
		cout << "Destroy Foo: " << this->number << endl;
	}

	virtual void print() {
		cout << "Foo!" << endl;
	}
	
	void print(int x) {
		cout << "Foo: Number: " << x << endl;
	}
	
	virtual void printNumber() {
		cout << "Number: " << this->number << endl;
	}
};

class Hoge : public Foo
{
	friend void printValue(Hoge &hoge);

private:
	int value;
	
	
public:
	Hoge(int value) : Foo(value * 3) {
		this->value = value;
	}
	~Hoge() {
		cout << "Destroy Hoge: " << this->value << endl;
	}
	
	int setValue(int value);
	int getValue(); 
	int operator + (Hoge & hoge);
	int operator ++();
	int operator ++(int n);
	void print();
	void print(int x);
};


int Hoge::setValue(int value) {
	int oldvalue = this->value;
	this->value = value;
	return oldvalue;
}

int Hoge::getValue() {
	return this->value;
}

int Hoge::operator + (Hoge & hoge) {
	return this->value + hoge.value; 
}

int Hoge::operator ++() {
	return ++this->value;
}

int Hoge::operator ++(int n) {
	return this->value++;
}

void Hoge::print() {
	cout << "Hoge!" << endl;
}

void Hoge::print(int x) {
	cout << "Hoge: Number: " << x << endl;
}

void printValue(Hoge & hoge) {
	cout << "value: " << hoge.value << endl;
}

int main() {
	Hoge hoge(13), fuga(22);
	Foo &foo = hoge;
	
	cout << hoge.getValue() << endl;
	cout << hoge.setValue(55) << endl;
	cout << hoge.getValue() << endl;
	cout << (hoge + fuga) << endl;
	cout << ++fuga << endl;
	cout << fuga++ << endl;
	
	foo.print();
	foo.print(123);
	foo.printNumber();
	
	hoge.print();
	hoge.print(123);
	hoge.printNumber();
	
	printValue(fuga);
	
	return 0;
}