相互参照のクラスをヘッダファイルだけで実現
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
TrackBack URL : http://www.thinkridge.com/modules/wordpress/wp-trackback.php/72
この投稿には、まだコメントが付いていません