• ベストアンサー

C++Builderのクラス

普段、新規アプリケーションの作成で、TForm1クラスでプログラミングしています。ここに、例えば、Xクラスなどを追加作成したいのですが、.hファイルに記述するのか、.cppファイルに記述すべきなのか教えてください。

  • teo98
  • お礼率27% (68/244)

質問者が選んだベストアンサー

  • ベストアンサー
  • kmb01
  • ベストアンサー率45% (63/138)
回答No.3

No.1です。 unit2.h, unit2.cppについてはNo.2の回答のようにしてもらうとして、 >Form1から、変数Aを参照出来ません。 変数が宣言されていないからです。 (クラスと全然関係ない関数main内で宣言されたものに TForm1::Button1Clickからアクセスできないし、 mainのローカル変数はmain終了時に破棄される) Xの存在期間がTForm1::Button1Click内だけでいいなら TForm1::Button1Click内のローカル変数として宣言すればいいし、 TForm1::Button1Click終了時も値を保持したい、 TForm1クラスの他のメンバ関数でも使用したいのであれば TForm1クラスのメンバ変数(もしくはグローバル変数)にすればいいです。 あと、 >(ファイル->ユニットヘッダーファイルの追加でもいい) やっぱり自分で書いたほうがいいです。 自分ならこうします //unit1.h #ifndef Unit1H #define Unit1H //---------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include "Unit2.h" // <----------------------追加 //---------------------------------------------------- class TForm1 : public TForm { __published: // IDE 管理のコンポーネント TButton *Button1; TEdit *Edit1; void __fastcall Button1Click(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); //オブジェクトインスペクタで追加 private: // ユーザー宣言 X *c; // <----------------------追加 public: // ユーザー宣言 __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif //unit1.cpp #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { c = new X; c->A = 19; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Edit1->Text = IntToStr(c->A); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { delete c; } //---------------------------------------------------------------------------

teo98
質問者

お礼

Xの存在期間に関する説明と、具体例を有難う御座います。unit2内でXをdeleteしない限り、Xは存在し続けるのかと考えておりました。 No1の御返事も、No3の御返事も、当方の悩んでいることに対して直接的な御説明でした。 解決できそうです。

その他の回答 (2)

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.2

No.1の回答に対する補足のソースについて unit2.cppにmain()があるのを削除。 というか、unit2.hでclass Xのメンバ関数定義まで記述しているので、この場合unit2.cppそのものが不要です。 unit2.hでインクルードガードがおかしい。#endifはファイルの末尾に移動。 取り敢えずこれで動作するはずです。 以下は補足ですが。 ヘッダファイルで関数定義までするなら普通こうします。 //unit2.h #ifndef Unit2H #define Unit2H class X { public:  int A;  X() { //処理 };  ~X() { //処理 }; }; #endif 通常はヘッダでクラス定義、cppファイルで関数定義です。 //unit2.h #ifndef Unit2H #define Unit2H class X { public:  int A;  X();  ~X(); }; #endif //unit2.cpp #include "unit2.h" X:X() { // } X:~X() { // } あと、ヘッダファイルのインクルードは必要なものに限るようにしましょう。そのソースだとunit2.cppにunit1.hは必要ありません。

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.1

新規ユニットを追加して.hファイルで宣言、.cppファイルで定義するのがいい。 そしてフォームの.cppファイルで新規ユニットの.hファイルをインクルードする。 (ファイル->ユニットヘッダーファイルの追加でもいい) フォームの.cppファイル内で宣言、定義することも出来るが、 宣言した行より下でないとそのクラスが使えないし、探しづらくなる。 新規クラスは新規クラスで一まとめにしておいたほうがいい。

teo98
質問者

お礼

漠然とした質問で申し訳ありません。 複数のFormクラスを使ったプログラミングから脱却出来そうです。 回答No.3で頂いた具体的なコードにて、トライしてみたいと思います。

teo98
質問者

補足

プログラミングの方針についてのアドバイスを有難う御座います。何となく記述できそうな感じですが、Form1から、変数Aを参照出来ません。C++Builderで、TForm以外のクラスの変数を扱う場合には、unit2に、どのようなコードを記述すれば良いのでしょう? unit1.cppが、 #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "Unit2.h" //---------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //---------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Edit1->Text = IntToStr(X().A); } //---------------------------------------------------- unit1.hが #ifndef Unit1H #define Unit1H //---------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //---------------------------------------------------- class TForm1 : public TForm { __published: // IDE 管理のコンポーネント TButton *Button1; TEdit *Edit1; void __fastcall Button1Click(TObject *Sender); private: // ユーザー宣言 public: // ユーザー宣言 __fastcall TForm1(TComponent* Owner); }; //---------------------------------------------------- extern PACKAGE TForm1 *Form1; //---------------------------------------------------- #endif unit2.cppを #pragma hdrstop #include "Unit2.h" #include "Unit1.h" //-------------------------- #pragma package(smart_init) //-------------------------- int main() { X c; c A =19; } unit2.hが #ifndef Unit2H #define Unit2H //---------------------------- #endif class X{ public: X();//コンストラクタ ~X();//デストラクタ int A; private: }; //---------------------------- //コンストラクタの定義 X::X() { // int *A = new int; } //---------------------------- //デストラクタの定義 X::~X() { // delete A; } //-----------------------------

関連するQ&A

  • 初心者です。VisualStudioについて教えてください。(C++)

    初心者です。VisualStudioについて教えてください。(C++) VisualStudioのWindowsフォームプロジェクトを作成すると 「Form1」という簡易画面が自動で作成されます。 その画面にボタン等を追加していくと、そのボタン押下時の処理が 「Form1.h」にどんどん追加されていきます。 なぜヘッダファイルに処理の実装を記述していくのでしょうか? 基本的に、ヘッダとは関数やクラスを定義するだけのもので 実装はcppファイルに記述していくものだと研修等で教わったのですが。 なぜなのでしょう? ご教授下さい。 また、「Form1.h」ではなく「*.cpp」ファイルに実装を記述したい場合 どうのようにすればよいのでしょうか?

  • Visual C++ 6.0 でクラス表示が消えてしまう

    『3週間完全マスターVisual C++ 6.0 』という本を参考に、Mouse という以下のプロジェクトを始めました。 Mouse のアプリケーションタイプ: 以下に示すターゲットのダイアログベースアプリケーション: Win32 作成されるクラス: アプリケーション: CMouseApp クラス ; Mouse.h , Mouse.cpp ダイアログ: CMouseDlg クラス ; MouseDlg.h , MouseDlg.cpp 特徴: + システムメニューにバージョン情報を付加 + 3D コントロール + 共有 DLL を使用 (MFC42.DLL) + ActiveX コントロールのサポート + リソースの言語: 日本語 発生している問題は、この中の CMouseDlg というクラスにメンバー変数を追加するためにワークスペースウィンドウの ClassView タブを選択し、Mouse クラスのツリーを展開したのですが、CAboutDlg, CMouseApp, グローバルという3つのクラスしか表示されず、肝心の CMouseDlg というクラスが全く表示されず、メンバー変数を追加したくてもできない、という状況です。ソースファイル内を探せば確かに CMouseDlg クラスは存在する(正確にはMouseDlg.hというヘッダーファイル内に)のですが、ワークスペースウィンドウ内に表示されない理由がわからず困っています。 もっと正確に言いますと、プロジェクトを開始した直後にワークスペースウィンドウで Mouse クラスのツリーを展開すると、ちゃんと CMouseDlg クラスは表示されるのですが、その後 ClassWizard を使って MouseDlg.cpp というインプリメンテーションファイル内にある、ある関数にコードを追加しようとすると、突然 CMouseDlg クラスがツリー表示から消えてしまいます。 どなたか理由のわかる方がいましたら御教授ください。説明が足りなければいくらでも補足します。宜しくお願いします。

  • Visual C++ 2005 MFCアプリのクラス作成について

    Windows XP SP3 Visual C++ 2005 pro MFCアプリケーション シングルドキュメント 以上の環境でアプリケーションを作りたいと思っています。 C++は、C言語をベースという意味ではそれなりにはわかっているつもりです(自信はないですが...)。 本当はSDKを学んだ方がよろしいんでしょうが、時間の都合上MFCでやることにしました。 ちなみに、VC++を使ったプログラミングは初めてのものです。 そこで質問なのですが、 通常のC++においてクラスを作るときは、cppファイルとhファイルで分けてつくってmainのcppでインクルードしますよね。 VC++ MFCも 「C++クラスの追加」 でウィザードを利用してあるクラスAを作成てみまして、わかる方にはわかるでしょうけど、もちろん以下のように出力されました。 A.h------------------ #pragma once class A { public: A(void); public: ~A(void); }; A.cpp---------------------- #include "A.h" #include "StdAfx.h" A::A(void) { } A::~A(void) { } そしてとりあえず、その状態で何も手を加えずにとりあえずコンパイルにかけてみたところいきなり以下のようなエラーが出ました。 error C2653: 'A' :識別子がクラス名でも名前空間名でもありません。 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません warning C4508: 'A' : 関数に戻り値の型が指定されていません。戻り値を void 型と見なします。 error C2653: 'A' : 識別子がクラス名でも名前空間名でもありません fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します 何も手を加えていない状態でこのようなエラーが出るということは、どこかでこのhやcppをインクルードする必要があるのだろうとは思います(でもそういう類のことはウィザードで作成した際に、VC++が自動でコーディングしてくれたりしないのでしょうかね...)。 むしろ、MFCでこのような単純なC++クラスを作ること自体があまり好まれないことなのでしょうか。 もちろんこのクラスを作っていってから、ある処理をさせていこうと思っているので、自分としては以前から行っていたC++のようにコーディングしていきたいと思うのですが、もし好ましくないようならどのファイルにMFC的ではない、ただのC++的なクラスを定義したりすればよろしいのでしょうか。 もしくは、好ましくなくても何らかの対処方法があれば教えていただきたく思います。 Webで調べても MFCクラスの作成などのことしか書いてないので、ちょっとわからなくて困っています。よろしくお願いします。

  • クラスのメンバ変数の宣言方法

    現在、プロジェクト内に”class PACKAGE TNumberEdit : public TEdit”というクラスを持った”NumberEdit.h”、”NumberEdit.cpp”ファイルを追加して、 Unit1.hファイル内の”class TTestForm : public TForm”このクラス内のpublicにメンバ変数として ”TNumberEdit *NumberEdit1;” このように宣言しました。 そして、 __fastcall TTestForm::TTestForm(TComponent* Owner) : TForm(Owner) { NumberEdit1 = new TNumberEdit(this); } //--------------------------------------------------------------------------- このようなプログラムを書くと次のようなエラーが出てきます。 [ILINK32 エラー] Error: 未解決の外部参照 'TNumberEdit::' が C:\MYWORK\....\CPP_BUILDER_2009\TEST_NUBEREDIT\DEBUG\UNIT1.OBJ から参照されました [ILINK32 エラー] Error: 未解決の外部参照 '__fastcall TNumberEdit::TNumberEdit(Classes::TComponent *)' が C:\MYWORK\.....\CPP_BUILDER_2009\TEST_NUBEREDIT\DEBUG\UNIT1.OBJ から参照されました このようなエラーを回避する方法はありますでしょうか?どうぞ教えて頂きますよう、お願い致します。

  • VisualStudio2005 C++ クラスの追加について

    C/C++カテゴリですが質問内容はVisualStudio(C++)です。 当該しそうなカテゴリがなかったのでこちらに質問させて頂きます^^ [プロジェクト]-[クラスの追加]からクラスを作成する際、クラス名などをウィザード上で入力したら、.cpp/.h ができますよね。 内容としては、コンストラクタとデストラクタが書かれています。 これに決まったファイルコメントを同時に出力したいと考えています。 下に出力イメージを記します。 test.hの中身 ----------------------------------------------------------------- /*************************************************** * testクラスの宣言 * @author : * @see : ***************************************************/ /*↑を一緒に出力したい*/ /*↓は今まで通りの出力*/ #pragma once class test { public: test(); ~test(); }; ----------------------------------------------------------------- こんなことできますでしょうか? ・クラス作成ウィザードの実態はこいつでここをこう拡張すればできる ・クラスのテンプレートなるものがいて、そこに書いてやればいい のような回答で結構です。 ご存知の方はご教授ください:-)

  • C++ Builderでユニットの追加

    趣味でプログラミングを行ってますCerapodaと申します。 Builderを使って1つのFormと1つのCpp,hファイルを使ったプログラミングならある程度のところまで出来ると思っているのですが 以前違うプロジェクトで作った関数を新たなプロジェクトで使おうとして いちいちコピー&ペーストするのも大変なので ひとつのユニット&ヘッダーファイルとしてインクルードして使いたいなと思いました。 そこで http://www.osakac.ac.jp/labs/matsuura/japanese/program/C++Builder/Project/projectManyForm.htm このページを参考にしてUnit1とUni2を作成し Unit2に double Analysis::Function(double val) { return(1.0-val); } の関数を追記。 Unit1のcppに C.Function(0.5); と書き加えたのですが [リンカ エラー] 外部シンボル '_C' が未解決… とエラーが表示されてしまいます。 どこに問題があるのか教えていただければ幸いです。 情報が足りない場合は、補足しますのでよろしくお願いします。 また、このような作業で参考になるサイト,URL等ありましたら教えていただけると幸いです。 よろしくお願いします。

  • VC++6.0で、ダイアログを新規に作成し、クラスウィザードでそのダイ

    VC++6.0で、ダイアログを新規に作成し、クラスウィザードでそのダイアログにクラスを割り当てる時 「クラス"CAbcDlg"のファイル(..¥AbcDlg.h, ..¥AbcDlg.cpp)を開けません」という エラーメッセージが出て、新しいクラスを作れません。何故でしょうか? 注1)正しく作れることもあります。 注2)出来てしまったAbcDlg.hとAbcDlg.cppファイルを削除して、   同じ操作をすると新しいクラスは作れます。

  • VC++ 6.0 でのCMainFrameクラスの作り方を教えてくださ

    VC++ 6.0 でのCMainFrameクラスの作り方を教えてください OSはWindows XPです。 MainFrame.cpp MainFraem.h ファイルはどちらもない状態です。 新規作成方法を教えてください。

  • C++BuilderでVector

    普段、vectorコンテナの可変長サイズ指定の特徴を利用していますが、一塊のコンテナの関数間でのやり取りについて、アドバイスを御願いいたします。 1)関数の引数としては、ポインタ渡しになるのですか?どんな記述になるのでしょう? 2)アクセス制限のpublic:欄に追加することで、他のクラスから参照することは可能になりますか?どんな記述になるのでしょう? 3)他の方法はありますか? よろしく御願いいたします。

  • ClassViewからクラスが消えました。復旧方法を教えてください。

    ClassViewからクラスが何故か消えてしまいました、復旧する方法を教えてください。(FileViewには.cppも.hもあります。) ダイアログを作りクラスウィザードでクラスを新規作成しそのクラスのソースファイルを直していた所、ClassViewからクラスが消えました。原因と復旧する方法を教えてください。