今VC6.0のconsole applicationでクラスを使った
簡単なプログラムを作っています。
今、クラスが二つあって、そのクラスのメンバがもう一方のクラス型のメンバを
お互いに持つという場合…例えば(分かると思いますが)
class A{
B x;
…
}
class B{
A y;
…
}
という場合、二つのクラス定義を異なるヘッダファイルに分けたいのですが
どうすればいいのでしょう。(今は一つのファイルでやってます)
一度やってみたら何百というエラーが出ました。無限ループになるらしいです。
多分#ifndefとかに似たような記述をするのだと思うのですが具体的に
どういう記述なのか、自分で調べた範囲では載ってませんで、ここに至りました。
どうかお願いします。
結論から言うと'不可能'です。
クラスのサイズが無限大になってしまいます。
他方がポインタであればなんとかなります。
class B;
class A {
B* pb;
...
};
class B {
A a;
...
};
失礼しました。↑ではポインタではないですが実際はポインタです。
今ちょっとやってみたのですが全くだめだったのですが…
επιστημηさんの書かれたのはプロトタイプ宣言をすればいいというような
ことだと思うのですがやはりだめでした。
もしかすると勘違いされてるかもしれませんが、問題なのは
そういう二つのクラスを作れるかどうかではなく、
そういう二つのクラスのクラス定義を別々のヘッダファイルに書けるか、
ということです。
今一応一つのヘッダファイルに記述している状態でちゃんと動いています。
それと、こういう二つのクラス、という例を挙げたかっただけなので
わざと正確に書きませんでしたが、実際の記述は
class A{
class B* x;
…
};
class B{
class A* y;
…
};
と言う風にしています。
こういうことでいいんでしょうか?
Aクラスのヘッダファイル ----------
#ifndef _CLASSA_H_
#define _CLASSA_H_
#include b.h //クラスB インクルード
class A {
class B* pb;
}
#endif //_CLASSA_H_
---------------------------------
Bクラスのヘッダも同じ形で。
> 今ちょっとやってみたのですが全くだめだったのですが…
> επιστημηさんの書かれたのはプロトタイプ宣言をすればいいというような
> ことだと思うのですがやはりだめでした。
クラス宣言をしておけば可能だと思います。
何をどうして何が起こって何故だめだと判断したのかを書いて頂けませんか?
(例)
a.hには以下のとおり
----------
class B;
class A{
class B* x;
…
};
----------
b.hには以下のとおり
----------
class A;
class B{
class A* y;
…
};
----------
西風さんの書かれた方法でできました。ありがとうございました。
#ifndef #defineの位置を間違って覚えていました。
インクルードの記述の後に置いてしまっていました。
もしかして#ifndef #defineくらいのことは
分かっていて当然だと思われてるんでしょうか。
それともこれを書かなくてもできるんでしょうか?
επιστημηさんとMASATOさんは書かれていませんが…
書かないで(位置を間違えたままで)やったらできませんでした。
ネストがどうとかヒープ領域を使い果たしたとかというエラーが出ました。
どうやらここで質問するときはOSやVCのバージョンに加えて
自分のプログラミング歴も示す必要があるようですね。
買い被られると困りますから。これから気をつけます。
っちゅーか多重インクルード防止は結構なFAQだから・・・
あと、VC6なら #pragma once っていうのもある。
それと、あまり関係ないですがちょっと気になったので、
『こう書くとエラーがなくなる』『こう書くとエラー』
というような覚え方ではなくて、
そのディレクティブをプリプロセッサがどう扱ってコンパイラからどう見えるか考えると、
エラーの意味も一つ一つわかってくると思います。
>それともこれを書かなくてもできるんでしょうか?
できる場合もありますけど、インクルード順によってかなり複雑なことになったりします。
なので、多重インクルード防止は常にするのがセオリーです。
先の例なら、A,B ともヘッダではインクルードをせず、
ヘッダ内ではお互いの内部構造を使用せず名前を宣言し使用するにとどめ、
実装ファイルで相手のヘッダをインクルードするようにすれば、
(要するにコンパイル単位ごとに定義を一度のみにするようにすれば)
可能ではあります。
> もしかして#ifndef #defineくらいのことは
> 分かっていて当然だと思われてるんでしょうか。
'ふつーやるだろそのくらい'と思っています。
> それともこれを書かなくてもできるんでしょうか?
> επιστημηさんとMASATOさんは書かれていませんが…
'いちいち書かなくてもわかってるだろ'と思っています。
> επιστημηさんの書かれたのはプロトタイプ宣言をすればいいというような
> ことだと思うのですがやはりだめでした。
え? プロトタイプ宣言?
class X; // これのこと? これはプロトタイプではありません。
...
class X { ... }
どうもすみませんでした。
ここのような高レベルなところでするような質問ではなかったようです。
もっと初心者よろしく参考書と初心者サイト漁りまくってから来ることにします。
面倒おかけしました。
>え? プロトタイプ宣言?
他にどういったらいいか分からないから適当に書きました。
「みたいなの」と書けばよかったですね。
(え?とか言われても…)
> ここのような高レベルなところでするような質問ではなかったようです。
> もっと初心者よろしく参考書と初心者サイト漁りまくってから来ることにします。
> 面倒おかけしました。
多重includeの抑止は '高レベル' とは思えないんだが...
「自分が何を知らないか」を整理することは難しいですが、
「質問者が何を知らないか」を回答者が知ることはもっと難しいのです。
対話をしながら問題点を絞り込んで解決に至る、という過程は避けられないでしょう。
何を言いたいかというと、そんなに敷居の高いところではないので、
またきてください、ということ。
静さんは最低限のルールは十分守れているように感じますので。
全然回答なんかしてない人の横レスでした。
>多重includeの抑止は '高レベル' とは思えないんだが...
何だかバカにされてるようで捨て置けません。
だれもそれが高レベルと言ってるのではありません。
読めば分かる文章にしたつもりですが「高レベルなところ」
の「ところ」はこのラウンジの場を指しているのであって
多重インクルード抑止が高レベルなどとは一言も言ったつもりはありません。
言いたかったのは、私の質問がC++言語の基本的なことを聞いているのに対して
他の方々の質問はMFCなどの高機能なことについてのことがほとんどで、
回答者の方々はどなたもそういった領域まで通じてらっしゃる方で、
そういう点でこのラウンジが高レベルと言ったまでです。
そして、そんな高レベルな場で低レベルな質問をした自分を恥じただけです。
まぁ、この意味での高レベルですら高レベルでないと言われるなら
私のプログラミングについての認識が甘すぎたというだけの話です。
私は情報の提示の不十分さは認めたつもりですし
それによって面倒をかけたことを謝罪もしたつもりです。
そして私の未熟さもおわびしたつもりです。
つもりつもりで伝わっていなかったら無意味ですが、それは置いておいて、
>多重includeの抑止は '高レベル' とは思えないんだが...
とさらに追い詰める発言をすることに何の意味があるのでしょうか。
初心者のくせにやたら高慢なやつだ、とお気にめさなかったのなら謝ります。
もっともっと低姿勢になるべきだったかも知れません。
ただ、あんな言われ方はどうしても納得がいきません。
ただ見下してバカにするためだけの書き込みとしか思えません。
たいちうさんのお心遣いはまことにありがたいですが、これで私も
最低限のルールを破ったわけです。これでまた来るわけにはいきませんね。
そもそもやはり場違いだと思うのでもっと他人に頼らずに勉強することにします。
これをご覧の皆様、管理人様、不適切な書き込みをしてすみませんでした。
完全に個人的な意見で質問とは無関係になりますけど、書き込みさせてください。
読み流してしまってもかまわないです。
>多重includeの抑止は '高レベル' とは思えないんだが...
これは僕も、ちょっとヒドイんじゃないかな~とは思いました。
静さんは、質問者としての態度や内容も
しっかりとしてる方だと思ってるので(少なくとも僕は)。
ただ、ちょっと調べ方が上手くないのかな、、とは思いましたけど。
それから、此処は高レベルってわけでもないと思います。
だいぶ前の雑談掲示板の方ですけど、
>敷居が高いと言われてしまうと残念です。
>やさしいレベルの掲示板ですし初心者ももちろん歓迎です。
と、管理人さんもこう言って(書いて)いますし。
以上、僕の勝手な意見でした。
ずいぶんと気分を害されたことを、まずお詫びします。
ここは決して高レベルではありません。
多重インクルードの抑止も高レベルではありません。
だからこの質問はここにふさわしくないとは考えていません。
...という主旨だったのですが。