かずきのBlog
C#やJavaやRubyとメモ書き

目次

Blog 利用状況
  • 投稿数 - 426
  • 記事 - 1
  • コメント - 461
  • トラックバック - 112
ニュース
  • 思い出は、いっぱい。
コメント
プログラマ的自己紹介
  • C#とRubyを趣味で。Javaを仕事で使ってやってます。 WPFをコツコツ勉強中。 IDE大好き。Visual Studio, Eclipse, NetBeansを使用中
お気に入りのツール/IDE
  • Visual Studio 2008 std
  • Eclipse
  • NetBeans6.0以降
  • 自作のツール
プロフィール
  • 大田 一希
  • 1981年1月30日産まれ
  • AB型
  • 左利き
経歴
  • 1993年 海田中学校 入学
  • 1996年 広島県立安芸南高等学校 入学
  • 1999年 某大学 環境情報学科 入学
  • 2003年 某大学 大学院 環境学研究科 入学
  • 2005年 就職して上京
  • 今に至る
アクセサリ
  • あわせて読みたい
  • ログ解析ネット証券

書庫

日記カテゴリ

 

元の記事: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++って強力だと感じるひと時。でも、こういうのに浸ってるときって実はやりすぎてることが多い。
はてさて今回はどうだろう…。

投稿日時 : 2008年3月4日 0:08
コメント
  • # re: [C#][Java][Ruby][C++]問題で~す!に答えてみる
    かずき
    Posted @ 2008/03/04 0:25
    実行結果書いてなかった。
    ★Parent<ChildA>
    ParentA::Cooking
    ChildA::Study
    ChildA::Study
    ChildA::Study

    ★Parent<ChildB>
    ParentA::Cooking
    ChildB::Study
    ChildB::Study
    ChildB::Study

    ★Parent<ChildA>
    ParentB::Cooking
    ChildA::Study
    ChildA::Study
    ChildA::Study

    ★Parent<ChildB>
    ParentB::Cooking
    ChildB::Study
    ChildB::Study
    ChildB::Study
  • # re: [C#][Java][Ruby][C++]問題で~す!に答えてみる
    myugaru
    Posted @ 2008/03/04 5:45
    おはようございます!さっそくのご解答ありがとうございます。
    templateめっちゃカッコイイっすね!しかーし・・・これでは問題を満たしておりません。
    問題は入れ子クラスの特性でございます。
    C++でもたぶん可能だと思いますが中のクラスから外のクラスのprivate staticな変数とかかを参照できる事が今回の一番難しいところであります。
    では時間ございましたら再挑戦お願いしますww
  • # [Ruby]問題でーすに答えてみる
    かずきのBlog
    Posted @ 2008/03/05 0:31
    [Ruby]問題でーすに答えてみる
タイトル  
名前  
Url
コメント