元の記事:http://blogs.wankuma.com/myugaru/archive/2008/03/03/126036.aspx
元の記事から引用
問題:似たような入れ子になっているクラスがいくつかあって困っている。親同士、子同士はそれぞれ基底クラスを定義してまとめられそうだ。しかし親クラスは子クラスに依存しているところ(List部分)がある。どうまとめればカッコよいか?
class ParentA
{
List children;
public void cooking()
{
}
public class ChildA
{
public void study()
{
}
}
}
class ParentB
{
List children;
public void cooking()
{
}
public class ChildB
{
public void study()
{
}
}
}
とりあえず感覚的にtemplateの出番かな。C++/CLIさん出番です。
// Question.cpp : メイン プロジェクト ファイルです。
#include "stdafx.h"
using namespace System;
using namespace System::Collections::Generic;
// 親の抽象クラス
template
ref class Parent abstract
{
public:
// 子クラスの型
typedef TChild ChildType;
public protected:
// 子クラスのリスト
property List ^Children;
public:
// childrenのインスタンスを一応作っとく
Parent()
{
Children = gcnew List();
}
// 一応仮想デストラクタ C++/CLIではいるんだっけかな?
virtual ~Parent() {}
// 後で、オーバーライドしてくれ!
virtual void Cooking() abstract;
};
// 親の実装例A
template
ref class ParentA : public Parent
{
public:
virtual void Cooking() override
{
Console::WriteLine("ParentA::Cooking");
}
};
// 親の実装例B
template
ref class ParentB : public Parent
{
public:
virtual void Cooking() override
{
Console::WriteLine("ParentB::Cooking");
}
};
// 子の抽象クラス
ref class Child abstract
{
public:
// 後で、オーバーライドしてくれ!
virtual void Study() abstract;
};
// 子の実装A
ref class ChildA : public Child
{
public:
virtual void Study() override
{
Console::WriteLine("ChildA::Study");
}
};
// 子の実装B
ref class ChildB : public Child
{
public:
virtual void Study() override
{
Console::WriteLine("ChildB::Study");
}
};
// お試し関数
template
void Print(Parent ^parent)
{
typedef Parent ParentType;
typedef ParentType::ChildType ChildType;
Console::WriteLine("★" + ParentType::typeid->Name);
// 受け取った方の子を3人作って追加
parent->Children->Add(gcnew ChildType());
parent->Children->Add(gcnew ChildType());
parent->Children->Add(gcnew ChildType());
// 親のCookingスタート
parent->Cooking();
// 子供の勉強スタート
for each (ChildType ^child in parent->Children)
{
child->Study();
}
Console::WriteLine();
}
int main(array ^args)
{
// 親2x子2の組み合わせのtypedef
typedef ParentA ParentAChildA;
typedef ParentA ParentAChildB;
typedef ParentB ParentBChildA;
typedef ParentB ParentBChildB;
// 4パターンお試し
Print(%ParentAChildA());
Print(%ParentAChildB());
Print(%ParentBChildA());
Print(%ParentBChildB());
return 0;
}
C++って強力だと感じるひと時。でも、こういうのに浸ってるときって実はやりすぎてることが多い。
はてさて今回はどうだろう…。