昨日の続き

ちょっと長すぎるので後でまとめる予定。それに、家にソースもって帰るのが面倒だし、ひとまずここに置いとくということで。

#include 
#include 
#include 

using namespace boost;
using namespace std;

class IMeshi {
public:
	IMeshi() {}
	virtual ~IMeshi() {}
	virtual string getName() const = 0;
};

class IAji {
public:
	IAji() {}
	virtual ~IAji() {}
	virtual string getName() const = 0;
};

class Kyaku {
public:
	Kyaku() {}
	virtual ~Kyaku() {}
	void eat( const IMeshi& meshi ){
		cout << meshi.getName() << "を食べるぜ" << endl;
	}
};

class Shioaji : public IAji {
public:
	Shioaji() : IAji() {}
	virtual ~Shioaji() {}
	string getName() const { return "塩味"; }
};

class Satouaji: public IAji {
public:
	Satouaji() : IAji() {}
	virtual ~Satouaji() {}
	string getName() const { return "佐藤味"; }
};

class Mushi : public IMeshi {
public:
	Mushi() : IMeshi(), m_Aji( new Satouaji ) {}
	Mushi( shared_ptr< IAji > aji ) : IMeshi(), m_Aji( aji ) {}
	virtual ~Mushi() {}
	virtual string getName() const {
		return string( "蟲(" ) + m_Aji->getName() + ")";
	}
	shared_ptr< IAji > m_Aji;
};

template< typename Aji >
class Gyauza : public IMeshi {
public:
	Gyauza() : IMeshi() {}
	virtual ~Gyauza() {}
	virtual string getName() const {
		return string( "餃子(" ) + Aji().getName() + ")";
	}
};

int main()
{
	Kyaku marisa;
	shared_ptr< IMeshi > meshi;
	shared_ptr< IAji > shio( new Shioaji() );

	meshi.reset( new Mushi( shio ) );
	marisa.eat( *meshi ); // 蟲(塩味)を食べるぜ

	Gyauza< Satouaji > amaGyauza;
	marisa.eat( amaGyauza ); // 餃子(佐藤味)を食べるぜ

	Gyauza< Gyauza< Gyauza< Mushi > > > mushiGyauza;
	marisa.eat( mushiGyauza ); // 餃子(餃子(餃子(蟲(佐藤味))))を食べるぜ

	return 0;
}

最後は暴走気味。