• ベストアンサー

C++ クラスについて

クラスについて今勉強しています。 そこで質問なんですが クラスの中にクラスというのは実現可能なのでしょうか? クラスAの中にクラスBとクラスCが入っている状態で、 クラスAの中にある関数XでクラスBやCの関数を呼ぶような処理を目指しています。 またクラスAに宣言されている変数をクラスB,Cの中で変更したりできないでしょうか?

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> この状況ではクラス内で関数が大量にでき不自然さを感じ メンバ関数は本当に必要なものだけに限定し、それ以外は非メンバ、非friendの関数にするのが望ましいと思います。(今回の件に限らず、常にそうです) また、適切にテンプレートを組み合わせることで、かなりすっきりした構成になることがあります。一度検討してみてください。

Haruzion77
質問者

お礼

確かにメンバ関数をうまく使うことが重要だと感じました。 適切なテンプレートなど使うようにしてすっきりさせようと思います。 ありがとうございました。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> class ClassA{ >  public: >   int x; >   ClassB Bclass; >   void testA(); > }; これはクラスの中にクラスがあるのではなく、クラスの中にクラス型のデータメンバがある例です。したがって、まったく話が異なります。 > このような状態の場合xを変更するにはどうすればよいのでしょうか? 今回の例に限れば、ClassAはC互換構造体のようですので、thisからoffsetof(ClassA, Bclass)バイト分を引いてからClassA*にキャストすれば、とりあえずxにアクセスすることはできます。 ただし、ClassAのメンバではなくClassBには対応できません。 現実的な解決策としては、ClassBのコンストラクタでClassAへの参照なりポインタなりを受け取り、それをデータメンバとして保持するのが妥当です。 しかし、このような密な関係のクラスではなく、もっと別の解決策があるように思います。それについては、こんな簡単な例ではなく、実際に何をやりたいのかがわからないとどうしようもありません。

Haruzion77
質問者

補足

クラスの中にクラス型のデータメンバを追加するだけではやはり無理ですか ポインタを使う方法なら確かに私の言っていたことが実現できそうですが、やはり解決策としては適当ではないようですね 今作ろうとしているのですが流れでは while(1){ クラスA.Loop(); 以降その他処理 } このような状態になっています。 クラスAではLoop以外にほかの処理の関数もがあります。 class ClassA{ public:  void testA();  void testB();  void Loop(); }; void ClassA::Loop() {  testA();  testB(); } となっていました。 この状況ではクラス内で関数が大量にでき不自然さを感じ クラスの中でもうひとつ階層を作りそこで関数を作ろうと考えました。 void ClassA::Loop() {  a.testA();  b.testB(); } このような感じに使いたかったのですが。 他の方法を考えてみたいと思います。ありがとうございました

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> クラスの中にクラスというのは実現可能なのでしょうか? 可能です。 > またクラスAに宣言されている変数をクラスB,Cの中で変更したりできないでしょうか? メンバ変数をpublicにするか、クラスBおよびCをfriendにする必要があります。

Haruzion77
質問者

補足

回答ありがとうございます。 一応組んでみたものです。 class ClassB{  public:   void testB(); }; class ClassA{  public:   int x;   ClassB Bclass;   void testA(); }; void ClassA::testA(){  Bclass.testB(); } void ClassB::testB(){  x=0; //ここで呼び出せない } このような状態の場合xを変更するにはどうすればよいのでしょうか?

関連するQ&A

  • C++のクラス設計について

    Webや書籍をあたってみたのですが、なかなか解決しないので こちらで相談させいただこうと思い立ちました。 C++で書かれたプログラムを解析しているのですが、 ドキュメントは外部仕様書のみであとはソースコードだけ、という状態です。 コメントもほとんど書かれていないコードについて、リバースエンジニアリングを する必要があり、手始めにクラス図を作成してみました。 すると、複数のクラスでメンバ変数が重複しているのです。 クラスAに、クラスB・C・Dの変数の一部が宣言されていて、 クラスAとクラスBの間で重複している変数はすべてどちらのクラスもprotectedのstatic、 クラスAとクラスC・Dの間で重複している変数はクラスAではprotectedのstatic、 C・Dではprivateです。 クラスBとC・Dは継承関係にありますが、メンバ変数の重複はありません。 クラスAと他クラスは継承関係がなく、メンバ変数が多数重複しています。 クラスAの変数は20個ほどありますが、9割以上がB・C・Dで宣言されている変数と 重複している状態で、かつstaticのprotectedです。 Cはわかるのですが、C++はほとんど書いたことがありません。 アンチパターンなどもあたってみたのですが、上記のような設計についての記述は 見つけられませんでした。こういったクラス間での変数重複は「あり」なのでしょうか? これで情報が足りているかわかりませんが、何卒よろしくお願い致します。

  • クラスの分割

    画像処理のプログラムを書いているのですが、1つのクラスに必要な変数と関数をぶち込んだため、変数20~、関数20~、2000行くらいのクラスになっています。 このままでは見辛いので、クラスを処理ごとに分割して見易くしたいのですが、各関数でいくつか共通の変数を使用しているため上手く分割ができなくて困っています。 データのみのクラスを継承した子クラスを3つ作ってみたらインスタンスが3つできてしまい意味がありませんでした。 ↓の図に示すようなクラスを作りたいのですが、いくつか質問をさせてください       共通データクラス     /    |    \   子クラスA 子クラスB 子クラスC 1、変数20~、関数20~、2000行くらいのクラスは普通でしょうか?(分割する必要がありますか?) 2、↑の図はクラスの作り方として問題がありますか? 3、2で問題がない場合実現する方法として、仮想継承、関数に共通データのポインタを渡す以外に方法があるかどうか まだまだC++を勉強中で、便利な構造体程度にしか使えていませんが、どなたかご教授お願いします。

  • C++でのstringクラスの内部の挙動

    最近C++でクラスを理解し始めて疑問に思ったことなんですが。 string A = "abcdef"; という風に直感的にstringに文字列を代入出来ていたので何の疑問も持たず使っていたんですが、これをどのように実現しているか内部の挙動がよくわかりません。 srtcopyはやり方は面倒臭いですがこっちは単純に関数に値を渡しているだけなので理解出来ます。 内部で=演算子のオーバーロードをしているんじゃないかと思って、=演算子をオーバーロドした自分で作ったクラスでテストしてみたんですが Testclass A; A = "abcdef"; は可能ですが、stringの例のように変数宣言と同時に代入する Testclass A = "abcdef" としてみると、Testclass型への変換が出来ませんとなって、string型と同じ事が出来ません。 stringクラスの中でどのようにクラス宣言直後の代入をしているか教えてください

  • C# このクラス型という限定が何を意味しているのか

    まだC#で実際にコーディングできるレベルではないため ネット上のドキュメントを見ていますと 変数の型宣言にクラス名 関数の戻り値にクラス名 のような書き方を目にします 例 public classA x; public classA x(){}; 一般的には、どのように解釈されてますか? また、同様に宣言にインターフェイス名やデリゲート名を使ったもの public IEnumerator<int> x(){}; public delegateA x;など これら宣言時に具体名を記述する文は iintやchar型などの基本的な型宣言と比べて 内部の挙動と、実際の文がうまくリンクできず 少し頭の中が整理できればと思い質問してみました。 今、僕の頭の中で上記の例は ・参照型という宣言である(専用の修飾子がない) ・そもそも型の宣言ではない ・いわゆる定型文なので、これ以上の応用はなく深く理解する必要もない 一体どれが近いんだろう? という感じで困っています。

  • クラスの再定義について(C++)

    あるAというクラスを定義して適当にメンバ関数などを書いておいて、Bというクラスを定義するときに そのBの中でAの関数を使いたいときはどのようにすればいいのかわかりません。どうすればよいのでしょう? 勉強不足なものでどうぞよろしく。

  • 戻り値がクラスオブジェクト

    VB初心者でわからないので教えてください。 ある関数を呼び出して戻り値を取得するのですが、その戻り値がクラスオブジェクトとなっています。いろいろ調べてみましたが、いい結果にヒットしなかったので今回質問してみました。 言語はVB6.0です Function 関数A(A as String, B as String) dim C as Class1 set C = new Class1 Class1で宣言された変数に値を入れる処理     関数A = C end Function イメージはこんな感じです。 すみませんが解決策を教えてください。。。。

  • クラス構造をネストしたの宣言

    クラスA クラスB を使い、お互いに関連した構造にしたいのですが、宣言に困り質問させていただきました。 A.cpp ファイルは class A{ B b; }; のように、クラスB を含んだ状態です。クラスBもクラスAを含んだ状態です。 ここで、オブジェクトファイルを作成すべく、 $g++ -c A.cpp とすると、クラスBが宣言されておらず怒られてしまいます。 クラスBを先に宣言したり、ヘッダーファイルを作成しても、クラスBでもクラスAのオブジェクトを使っているので、やはり"定義されていない"とおこられてしまします。 C言語の関数を入籠にした場合は、プロトタイプを使用して問題を回避しましたが、クラスの場合でこれを解決する手段がわからず質問させていただきました。 どうかご教授ください。

  • 【C#】フォームクラスと他クラスとの連携について

    C#を勉強し始めたばかりの者です。 オブジェクト指向言語が初めてなので、オブジェクト指向的考え方が出来てないゆえの質問だとは思うのですが・・・。 質問内容ですが、フォームクラスと他のクラスとの連携方法がわかりません。 具体的に言いますと、フォームクラスで別のAというクラスを宣言し、そのクラスのB()メソッドを実行したときに中で発生した例外メッセージをフォームのコントロールで表示したい、という場合、どうすればよいのでしょうか? Doメソッドで例外メッセージをstringとして返し、それをフォームクラスの方で処理するしかないのでしょうか? お知恵を貸してください。よろしくお願いします。

  • 親クラスのポインタ、クラスを指定しないポインタ

    親クラス A (抽象メソッドX、Yの2つを持つ) と 子クラス B-1 (親はA、抽象メソッドX、Y、Zの3つを持つ) 子クラス B-2 (親はA、抽象メソッドX、Y、Wの3つを持つ) のように、子クラスでポリモーフィズムを実現しているとき、 クラスC   「実行時に、iniファイルに(1)と書かれていたら、B-1のクラスで実体化し、   iniファイルに(2)と書かれていたら、B-2のクラスで実体化する」  というクラスを作りたいです。 //////////////////////////////////////////////////////////////// 質問(1) その際、クラスCは、どうやってもZのメソッドや、Wのメソッドは書けない認識です。 (メソッド名もiniファイルから取るようにすれば別でしょうが。) この認識であっていますでしょうか? 質問(2) 逆に、XとYについては、それぞれ挙動の違う処理を行わせることができる認識です。 (クラスCで、親クラスAのポインタ型の変数を用意しておき、  そのポインタに、DLLのインスタンス化したものをいれておけば、  メソッドXとYについては実行可能という認識です)

  • c言語 関数宣言

    c言語で書かれたプログラムを見ていると、ちょっとわからない関数宣言がでてきました。 関数宣言をしているのだと思うのですが、これはいったいどういうことなのでしょうか。 grad_pf(x, a, yfit, dyda, ma) float x; float a[]; float *yfit; float dyda[]; int ma; {            処理・・・・・・・・ } 中括弧の前で宣言された変数はどういったものなのでしょうか。 よろしくお願いいたします。

専門家に質問してみよう