ログイン

2016年3月 弊社ホームページは新しくなりました。 https://thinkridge.com

メインメニュー

携帯公式サイト


携帯電話をもっと便利に
もっと楽しく


史上初の吹奏楽専門着メロサイト


POPで癒しでライトでとんがって気持ちのいい〜オルゴール着メロをあなたに

Magome

クラウドベースの MIDI シーケンサ Magome

音楽制作に興味のある方を対象に、スタンドアロンでも使え、ネットならではの面白さも兼ね備えた音楽制作アプリの提供を目指しています

for 携帯電話

https://thinkridge.com/m/
ケータイはこちらへ

2008年5月17日(土曜日)

相互参照のクラスをヘッダファイルだけで実現

カテゴリー: - takatsuka @ 00時29分52秒

struct ClassB;

struct ClassA
{
    int n;
    int Func(ClassB &b) {return b.n;}
};

struct ClassB
{
    int n;
    int Func(ClassA &a) {return a.n;}
};

こんなような、お互いを参照するクラスがあったとします。

しかし、これではコンパイルが通りません。
コンパイラが ClassA::Func を処理するときには、ClassB が分からないってことでエラーとなります。

そこで通常なら、ヘッダファイルに定義を書いて、実装はソースファイルに書くことになると思います。

— class.h —

struct ClassB;

struct ClassA
{
    int n;
    int Func(ClassB &b);
};

struct ClassB
{
    int n;
    int Func(ClassA &a) {return a.n;}
};

— class.cpp —

#include “class.h”

int ClassA::Func(ClassB &b) {return b.n;}

しかし、どうしてもヘッダファイルで完結させたい場合があります。
ヘッダファイルをインクルードするだけで使えるクラスってのは、なにかと便利です。

そんな場合は、こうすると解決することを思いつきました。

struct ClassB;

struct ClassA
{
    int n;
    int Func(ClassB &b) {return FuncT<0>(b);}
private:
    template <int dummy> int FuncT(ClassB &b)   {return b.n;}
};

struct ClassB
{
    int n;
    int Func(ClassA &a) {return a.n;}
};

無理やり template 関数を使います。(template の引数は使いません。)
これでコンパイルが無事に通ります。

ただ、試した環境は VisualStudio2005 と 2008 だけなので、古い環境などではエラーになることもあるのかもしれません。
というか、最初のコードでも無事にコンパイルしてくれるコンパイラもあるかもしれないっすね。

ちなみに、

template <int dummy=0> struct ClassAT
{
    int n;
    int Func(ClassB &b) {return b.n;}
};

typedef ClassAT<> ClassA;

こんな感じでもOKですが、余計な公開クラスが出来てしまうのが欠点すね。

 

以上、最近思いついた姑息テクです。
もっと良い解決策をご存知の方おられましたら、是非ご教授頂き度。

/*
相互参照するクラス自体が好ましくないのかな・・・?
*/


TrackBacks

このコメントのRSS

TrackBack URL : http://www.thinkridge.com/modules/wordpress/wp-trackback.php/72

この投稿には、まだコメントが付いていません

コメント

_CM_NOTICE

32 queries. 0.039 sec.
Powered by WordPress Module based on WordPress ME & WordPress

カレンダー
2008年 5月
« 4月   6月 »
 123
45678910
11121314151617
18192021222324
25262728293031
月別過去ログ
カテゴリ一覧
検索
最近の投稿
最近のコメント
投稿者ブロック