ポリシークラス

偉大なるid:uskzさんが以前mixiの日記で某ジェネリックプログラミングの本を紹介されていたので、
ちょっと前に購入しました。 え、積読リスト? 見えない見えない(^^
借り物の本とかあるのでなるべくそっちを優先して読んでいますが、
今日はちょっと気分転換にこっちの本を。


まず問題なのが、わたくしはC++を知らないという・・・笑
簡単なクラス定義はできますが、関数の中身は極めてC言語です。ありがとうございました。
なレベルです。 とりあえずテンプレートの勉強だけして挑んでみました。


C#等のジェネリックとテンプレートの違いが身を持って分かってきました。笑
ためしにC++のコードをC#で書き直そうとしてみたのですが、無残な姿になりました。


元コード

#include <iostream>
using namespace std;

template<class T> class Policy1
{
public:
	static T* CreateInstance()
	{
		cout << "Policy1 !!" << endl;
		return new T;
	}
};
template<class T> class Policy2
{
public :
	static T* CreateInstance()
	{
		cout << "Policy2 !!" << endl;
		return new T;
	}
};

class Hoge
{
public :
	void Hello()
	{
		printf( "hello, world.\n" );
	}
};

template<template<class> class Policy>
class Manager : Policy<Hoge>
{
public :
	void Run()
	{
		Policy<Hoge> p;
		Hoge *h = p.CreateInstance();
		h->Hello();
	}
};

int main( void )
{
	Manager<Policy1> m;
	m.Run();

	typedef Manager<Policy2> P2Manager;
	P2Manager p2m;
	p2m.Run();

	return 0;
}


原型をとどめていないC#2.0のコード

using System;
using System.Collections.Generic;
using System.Text;

using MyManager = Potato.Manager<Potato.Policy2>;//◆

namespace Potato
{
	public abstract class Policy
	{
		public virtual T CreateInstance<T>() where T : new()
		{
			return new T();
		}
	}
	public class Policy1 : Policy
	{
		public override T CreateInstance<T>()
		{
			Console.WriteLine( "Policy1 ?" );
			return base.CreateInstance<T>();
		}
	}
	public class Policy2 : Policy
	{
		public override T CreateInstance<T>()
		{
			Console.WriteLine( "Policy2 ?" );
			return base.CreateInstance<T>();
		}
	}
	public class Hoge
	{
		public void Hello()
		{
			Console.WriteLine( "VB !!" );
		}
	}

	public class Manager<P> where P : Policy, new()
	{
		P policy = new P();
		public void Run()
		{
			Hoge h = policy.CreateInstance<Hoge>();
			h.Hello();
		}
	}

	class Program
	{
		static void Main( string[] args )
		{
			Manager<Policy1> m = new Manager<Policy1>();
			m.Run();
			MyManager m2 = new MyManager();
			m2.Run();
		}
	}
}


C#のコードがC++のコードと全然似ていないのには色々と訳が・・・笑


最初は似せて書いていったのですが、そうするとMain内が
Manager,Hoge> m = new Manager,Hoge>();
という、ひどい状況になってしまいました。
C#では、template class Policy> ←これができない!)


んで、C++のように
Manager m = (ry
と書くために色々やっていたら(なんか観点間違ってる)、
結果として多くのものを犠牲にしてこうなりました。
でも結局usingでエイリアスを付けて使うという!


あ、本では、
WidgetManager>(ry
となっていて、Widgetと分かっているのにWidgetを渡すのはカッコ悪いよね
という話からそういうプログラムになりました。
# おいらのプログラムからは読み取れないので一応解説・・・笑



C#だと制約がきついのでどうしてもポリシーに共通のインターフェイスを通す必要があって、
C++みたく柔軟には書けない。
本には

重要な点として,従来のインターフェイスとは異なり,ポリシーのインターフェイスは緩やかに定義されたものとなっていることが挙げられます
と書いてありましたけどね(^^;
むむーん。。


今は、「ポリシー・クラスのデストラクタ」というところで足止めを喰らってます。笑
内容と言うか、C++の文法がわからn(ry
勉強してから出直しっすー。
その前に借りてるLisp本読んでしまわねばー


追記:
kazukiさんが自分流に書いてくださいました
ttp://d.hatena.ne.jp/okazuki/20070503/1178207262