- ベストアンサー
C言語(BCB)で双方向リストを操作する方法
Borland C++ Builder5 でプログラミングしています。 親Formで、ファイルを読み、双方向線形リストを作っています。 子Form(ダイアログ)で、この線形リストにノードを追加したいのですが、うまくコンパイル出来ません。 どなた様か、ご指導お願いします。 まず、構造体として次のように定義しています。(Form1のヘッダーファイル) typedef struct _UkeM{ char id[7]; // 途中略 struct _UkeM *beforP; struct _UkeM *nextP; } UkeM; UkeM *UkeTop, *UkeNow, *UkeEnd; 当然これらの定義は、子Formでも操作したいので、public: として定義されています。 親Formで領域を確保するには、 UkeNow = new UkeM; と実行し、最尾ノードのnextPなどにアドレスを格納しています。 この親Formでの処理はコンパイルも通り正しく実行されています。 さて、子Formで、このリストにノードを作ってつなげたい、と思っています。 子Formでは、単純に Form1->UkeNow = new Form1->_UkeM; とやってみたのですが、「型名が必要」というエラーで通りません。 どうも、newの右側が良くないようです。 子Formで、このリストを参照するだけなら全く問題なく操作できています。 (例えば、Label1->Caption = Form1->UkeNow->id;) newだけがうまく出来ません。 子Formでのnewのやり方についてご指導をお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> ところで、ついでに「突っ込みどころ満載」の部分をご指導いただけないでしょうか? > せっかくなので、ぜひ! std::listを使うべきだということと、予約済み識別子に関しては既に別の方が指摘されています。 std::listに関しては、もしC言語と兼用するのであれば使えない事情も分からなくはありませんが、Formのクラス有効範囲ではそれもなさそうです。 C++限定であれば、UkeMがなぜtypedef名なのかも謎です。 他に、もっと根本的なこととして、 > Form1->UkeNow = new Form1->_UkeM; コンパイルエラーはともかく、なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。
その他の回答 (5)
- jacta
- ベストアンサー率26% (845/3158)
> >std::listを使うべきだということ > C言語の延長で使っているので、この使い方は知りませんでした。 > 双方向リストは良く使うので、この部分を勉強したいと思います。 > 何か良い参考書(あるいはサイト)でもあればご紹介下さい。 一番わかりやすいのは、「C++標準ライブラリ チュートリアル&リファレンス」です。 > >なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。 > ある処理を行っている途中で、少量のマスターメンテナンスを行う必要があるのですが、その画面をダイアログで表示したため、子Formで線形リストに更新かけた、という理由です。 > このようは単純な発想しかありません。 UkeM型をFormのクラス有効範囲で定義すべきかどうかはわかりませんが、少なくとも線形リストの操作のような低レベルの処理は、Formクラスの内部(具体的にはメンバ関数や随伴関数等)で行うべきです。 そうでなければ、UkeM関連はFormクラスからは切り離すべきです。
お礼
ありがとうございました。 >一番わかりやすいのは、「C++標準ライブラリ チュートリアル&リファレンス」です。 やっぱりこれなんですね? 我々シロートは、これを読むのがむずかしい・・・。 でもがんばってみます。 >UkeM型をFormのクラス有効範囲で定義すべきかどうかはわかりませんが、少なくとも線形リストの操作のような低レベルの処理は、Formクラスの内部(具体的にはメンバ関数や随伴関数等)で行うべきです。 そうでなければ、UkeM関連はFormクラスからは切り離すべきです。 うーん、このレベルの話になると、やはり理解できません。 もう少し勉強しながら理解に努めます。 とりあえず、当面の問題は解決したので、これで完了とします。 std::listについては、今、サンプルプログラムを作って確認をし始めたところです。 単なるリストを作ることは出来ましたが、もう少し複雑なことについてはうまく出来ていません。 あらためて質問をアップします。 その時は、またご指導下さい。
- Tacosan
- ベストアンサー率23% (3656/15482)
typedef のところだけ: C++ だと, 他の識別子と衝突しない限り struct/union/class のタグも型名として認識してくれます. だから, struct UkeM { // なんか }; としておくだけで UkeM foo; とできます.
お礼
ありがとうございました。 なるほど、出来ますね。 数行のテストプログラムを作って確認してみました。 以後、このようにいたします。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
>「突っ込みどころ満載」の部分をご指導いただけないでしょうか? 僕なら"双方向線形リストを作って"いるのに突っ込む。 わざわざ作らなくても std::list<string> 使えばいい。
- jacta
- ベストアンサー率26% (845/3158)
突っ込みどころ満載ですが、それはさておき、 new Form1::UkeM; でよいのでは?
お礼
ありがとうございました。 お蔭様で役に立ちました。 ところで、ついでに「突っ込みどころ満載」の部分をご指導いただけないでしょうか? せっかくなので、ぜひ!
- Tacosan
- ベストアンサー率23% (3656/15482)
「_ で始まる識別子は使っちゃダメ」といいつつ, Form1 の型は知らないけど new で指定するのは型名だから new なんか::_UkeM の形になるはず.
お礼
なるほど。 先のepistemeさんといい、レベルが高くてすごいですね。 >std::listを使うべきだということ C言語の延長で使っているので、この使い方は知りませんでした。 双方向リストは良く使うので、この部分を勉強したいと思います。 何か良い参考書(あるいはサイト)でもあればご紹介下さい。 >C++限定であれば、UkeMがなぜtypedef名なのかも謎です。 このソースをBCB以外で使うことはありませんので、C++限定です。 が、私のレベルでは、なぜ謎なのかも分かりません。 何か名前を付けなくてはいけないので分かり易い名前を付けた、ということなのですが・・・。 >なぜクラスの外で上のような低レベルの処理を記述しないといけないのか理解に苦しみます。 ある処理を行っている途中で、少量のマスターメンテナンスを行う必要があるのですが、その画面をダイアログで表示したため、子Formで線形リストに更新かけた、という理由です。 このようは単純な発想しかありません。 達人の皆さんはどの様にやるのでしょうか?