• ベストアンサー

継承したポインタ

まだ経験が浅いので単純な理屈だと思うのですが、納得できる資料がなかったのでどうかご教授お願いいたします。 class AAA { DATA *pData; }; class BBB : public AAA { ..... }; こんな感じのクラスを用意し、実体をメイン関数内で作ったんですが、 AAA aaa; BBB bbb; aaa.pData->Rendering(); これだと上手くいくのに bbb.pData->Rendering(); これだとアクセス違反になるのはなぜでしょうか?

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.7

>その核をBBBに渡して作り、Rendering()を実行すると上手くいったんですが、これ以降、このように担当を作るたびに核を渡していくという解決法で良いのかどうか悩むところです。 既に動かすことが目的になっていて、クラスを継承している意味が無いんです。オブジェクト指向の継承の理解が不十分だと思います。 オブジェクト指向的には、 aaa.pData->Rendering(); としていること自体間違いです。オブジェクト指向のカプセル化を理解できていません。 >AAAはシステムの起動から終了までの管理を行うクラスで、最初は描画やリソースetcもこいつに仕切らせようとしてましたが、描画内容などを定義するのは描画担当だけでいいという考え方で切り分けようと思いました。 描画担当であるBBBがシステム担当であるAAAを継承する必要はないですよね。それに、pDataを必要とするのはBBBだけでAAAには不要なのでは? このままで良いのかは本人に任せるとしても、オブジェクト指向とC++をちゃんと使いたいなら最低限カプセル化と継承の勉強をお勧めします。

sanato
質問者

お礼

みなさまの回答を参考に四苦八苦しながら、それぞれ担当ごとにクラスを分けて、なんとなくそれっぽい形でまとめることができたように思えます。確かに描画クラスが継承したらカプセル化を崩してしまっていますね。 もっと精進しようと思います。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

「場所 0xcccccccc」ということからして, Visual C++ で初期化されていないポインタを使ったに 1票.

全文を見る
すると、全ての回答が全文表示されます。
回答No.5

bbb.pDataがヘンなとこ指してるからでしょう。

全文を見る
すると、全ての回答が全文表示されます。
回答No.4

再現できません。どちらもアクセスできません。 struct DATA { void Rendering() {} }; class AAA { DATA *pData; }; class BBB : public AAA { }; int main() { AAA aaa; BBB bbb; aaa.pData->Rendering(); bbb.pData->Rendering(); } error C2248: 'AAA::pData' : private メンバ (クラス 'AAA' で宣言されている) にアクセスできません。 error C2248: 'AAA::pData' : private メンバ (クラス 'AAA' で宣言されている) にアクセスできません。

全文を見る
すると、全ての回答が全文表示されます。
  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.3

えーと コンストラクタの実装はどうなってますか? ロベールのC++教室 http://www7b.biglobe.ne.jp/~robe/cpphtml/index.html 第3章 コンストラクタ http://www7b.biglobe.ne.jp/~robe/cpphtml/html02/cpp02003.html 第16章 派生と構築 http://www7b.biglobe.ne.jp/~robe/cpphtml/html02/cpp02016.html とりあえず言えることは、 pDataの初期化部分がどうなってるかですね。 AAAのコンストラクタで領域を確保しているのならば、BBBでもちゃんとAAAのコンストラクタを通る(実引数が一致してればですよ)はずなのでエラーは出ないはずですが、、

全文を見る
すると、全ての回答が全文表示されます。
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

クラスの継承はプログラム構造とデータ構造だけを継承します。 それに対してデータは、クラスの変数を作るたびにそのインスタンス毎に領域が作られます。 AAA aaa; BBB bbb; と成っていたら、aaaとbbbは別のメモリ領域を持ちます。 aaa->pData; bbb->pData; はメモリ的に違う変数なのです。 ちなみに、 AAA aaaA; AAA aaaB; と成っていても、 aaaA->pData; aaaB->pData; はメモリ的に違う変数となります。

sanato
質問者

お礼

うむむ。 みなさんのおっしゃってることが把握しきれないのですが、おそらく中身がちゃんとしてない方のpDataを使ったからということでしょうか。 AAAはシステムの起動から終了までの管理を行うクラスで、最初は描画やリソースetcもこいつに仕切らせようとしてましたが、描画内容などを定義するのは描画担当だけでいいという考え方で切り分けようと思いました。AAAにあるシステムの核となるポインタ?からしかpData(描画担当)は作れないので、その核をBBBに渡して作り、Rendering()を実行すると上手くいったんですが、これ以降、このように担当を作るたびに核を渡していくという解決法で良いのかどうか悩むところです。 ともかくありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.1

DATA *pDataがプライベートメンバーだから。 publicかprotectedメンバーなら派生クラスから参照できます。

sanato
質問者

お礼

回答ありがとうございます。 書き損じてすみません。そこは既にpublicにしてあります。 private メンバ にアクセスできません。 このような意味でのアクセス違反ではなく、 ハンドルされていない例外が発生しました: 0xC0000005: 場所 0xcccccccc を読み込み中にアクセス違反が発生しました。 このようなエラーが起きて困っている次第です。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 仮想関数と継承について

    #include <iostream> using namespace std; class AAA { public: virtual aaa() { cout <<"aaa(void)"<<endl;} }; class BBB : public AAA { public: virtual aaa(int a) { cout <<"aaa(int)"<<a<<endl;} }; int main() { BBB bbb; bbb.aaa();<--これがエラーになります。 return 0; } どうして、既定クラスの引数なしのaaa()はよぶことが できないのでしょうか?

  • 現在のクラスを生成したクラスに渡したい

    親クラスで生成した子クラス(ダイアログ)から親クラス(ダイアログ)の関数などを使えるようにしたいと思っております。 ちなみに継承クラスで親クラスの関数を使うのではなく、親クラスそのもの(ダイアログ表示)を子クラスから変更できるようにしたいです。 (簡単になりますが…)プログラムの構成は以下のようになっており、thisポインタを渡すか所でエラーが起こってしまいます。 ------------------------------------------------ class AAA { BBB *b; void classBBB{ b = new BBB(this); // こういうことがしたいが、できない void fun( int a ); // ダイアログの表示が変更する(予定) }; class BBB { AAA *a; BBB(AAA *pDlg){ a==pDlg; } void fun(){ int b; a->fun(b); } // 親クラスの関数を呼び出したい }; ------------------------------------------------ ただし、class Aとclass Bを生成する上位階層のプログラム構築をすることはなしとします。 ------------------------------------------------ こんな感じ AAA *a = new AAA(); BBB *b = new BBB(a); ------------------------------------------------ どうしてもclass AAAからclass BBB呼び出したいと思ってます。 何か良い解決法があれば、教えていただきたいです。 宜しくお願い致します。

  • C#でthisポインタのような感じで渡したい

    こんにちは。 C#で以下のようなことをしようとしましたら 「error CS1605: 読み取り専用なので 'this' は ref または out 引数として渡せません」 とエラーが返されてしまいました。 C++ではthisポインタを渡すことができますが、C#で似たようなことをするには どのようにすればよろしいのでしようか? public class AAA {   public AAA( ref BBB a )   {   } } public class BBB {   public BBB()   {     AAA aaa = new AAA( ref this ) ;   } }

  • 「自作クラスの型」にキャストする方法について。

    「自作クラスの型」にキャストする方法について。 Java初心者ですが、よろしくお願いします。 class AAA class BBB ※クラスAAAはクラスBBBのスーパークラス(直属のスーパークラスとは限らない)とします。 class CCC という3つのクラスがあるとして、 この場合、 class CCC{ AAA var; BBB bbb; void test(){ bbb = new BBB(); var = (AAA)bbb; //---★ } } というような、キャストは可能ですよね?(←確認1) 次に(確認1に問題が無い場合)、 クラスAAAとクラスBBBの格納場所(パッケージ関連の話です)について、 AAAとBBBがどういう位置関係にあるときに、上記のキャストは可能になるのでしょうか? AAAとBBBが同一パッケージ内にある時だけでしょうか?(←確認2[質問の核]) で、さらに、 上記の「---★」の所で、 AAAクラスにキャストする処理をしていますが、 この時、AAAクラスのコンストラクタは呼ばれるのでしょうか? (AAAをnewしていないけれど、キャスト処理でnewしたのと同じことになったりしますか?) また、これと同様の質問になりますが、 仮に、クラスAAAの設計が、クラスAAAのインスタンスが生成された場合に、 何らかのコールバック処理が行われるような設計の場合、 この (AAA)bbb というキャストによって、想定しているコールバック処理 は行われたりしますでしょうか?(←確認3) 初心者らしからぬ質問かもしれませんが、 どなたか、どうか分かりやすく教えて下さい。

    • ベストアンサー
    • Java
  • ポインタ配列について

    struct AAA{ char *aaa; char *bbb; }; main(){ struct AAA *BBB[36]; ... rtn = sub(BBB); ... rtn = subsub(BBB); } void sub(*BBB[36]){ ... for(i=0; i<3; i++){ BBB[i] = (struct AAA*)malloc(sizeof(struct AAA)); } ... } void subsub(*BBB[36]){ ... for(i=0; i<3; i++){ printf("[%s]\n", BBB[i]->aaa); } ... } このような流れのプログラムを組みたいです。 *BBB[36]に値を設定してその値を使うプログラムです。 "struct AAA"の内容を大量に受信するので*BBB[36]としました。 sub()、subsub()の引数の書き方*BBB[36]はあってますか? またsub()、subsub()関数の引数*BBB[36]は他にもっとシンプルなやり方があると思うのですが。 どなたか教えて下さい。 宜しくお願いします。

  • c++,ある関数のクラスから別のクラスの関数を呼ぶ

    c++で、あるクラスのメンバ関数から、別のクラスのメンバ関すを呼びたいのですが、どのようにしたらできますか? 例えば、以下のような単純なコードを考えています。やりたいことは、Aのメンバ関数であるaaa()からBのクラスであるbbb()を呼びたいと思っています。その理由を少し説明します。ここでは、Aというクラスとmain関数はオープンソースコードを例えています。できるだけ、元のオープンソースコードを書き換えずに新たな機能を拡張したいと思っています。そこで、Bというクラスを使って、元のオープンソースコードに機能を拡張しようとしています。このような理由なので、bbb()という関数はaaa()という関数から呼びたいです。メイン関数には何も書き加えないのがベストです。 現状では、実行すると「this is aaa」という出力しか出ません。ここに「this is bbb」の出力を加えたいです。クラスAとBにある程度コマンドを追加して、解決できないでしょうか。 #include <iostream> using namespace std; //------------------------------------------------------ class A{ public: void aaa(); virtual void bbb(){} }; //------------------------------------------------------ //------------------------------------------------------ class B : public A{ public: void bbb(); }; //------------------------------------------------------ //------------------------------------------------------ void A::aaa() { cout << "this is aaa \n"; bbb(); } //------------------------------------------------------ //------------------------------------------------------ void B::bbb() { cout << "this is bbb \n"; } //------------------------------------------------------ //------------------------------------------------------ int main() { A a; a.aaa(); return 0; } //------------------------------------------------------

  • C#でクラス継承について

    下記のようなコードは、可能なのでしょうか? // クラス定義 abstract class Base { int a; Public int A { get{ return a; } } } class Sub1 : Base { int b; public int B { set { b = value; } } }; class Sub2 : Base { // 中略 } static class Program { [STAThread] static void Main(string [] args) { Base aaa = new Sub1(); Base bbb = new Sub2(); func(aaa); // ここでCS1502, CS1503 func(bbb); // ここでCS1502, CS1503 } void func(Sub1 _aaa) { // 中略 } void func(Sub2 _bbb) { // 中略 } } コメントに書いたとおり、CS1502(引数が合わない)が出ます。 func((Sub1)aaa); の様にキャストしないと、動作させることは難しいでしょうか? ※ 実際のコードでは、func(aaa), func(bbb)の呼び出し部分をループでまわしたいと考えています。

  • ハンドルされていない例外が発生?

    C++にて作成したアプリを終了すると0xC0000005エラーが発生します。 エラー箇所は AAA *aaa //AAAは外部クラス(グローバル) void BBB{ aaaa = new aaa; aaa->ccc();} void CCC{ aaa->ddd(); delete aaaa; } メイン関数にてBBB→CCCの順で数回読んでいます。 エラーの原因として何が考えられるでしょうか? 開発環境はWindowsXP VC++6.0です。 よろしくお願いします。

  • classのdelete

    C++についてです。 class aaa; class bbb; とあったとします。 class aaaは、内部にclass bbb型の配列を 持っているとすると、aaaをdeleteする場合には aaaのデストラクタがcallされると思うのですが bbbのデストラクタは自動でcallされるのでしょうか (class bbbは、明示的にdeleteしないといけないのでしょうか?) 宜しく御願い致します。

  • オブジェクトの関連について

    クラスAAAとクラスBBBをインスタンス化し、それぞれ、aとbのオブジェクトとします。 mainメソッドから、bのbmethメソッドを呼び出し、さらに、Amethメソッドを呼び出し また、mainからもaのAmethメソッドを呼び出し可能にする方法はありませんでしょうか? まだ、Java初心者なもので説明も不十分かと思いますがよろしくお願いします。 class AAA{ void Ameth() { System.out.println("Aメソッド"); } } class BBB{ public AAA a; void bmeth(){ a.Ameth(); } } public class test{ public static void main(String arg[]) { AAA a = new AAA(); BBB b = new BBB(); b.bmeth(); a.Ameth(); } }

このQ&Aのポイント
  • 天地真理の歌唱力に感嘆しました。
  • 特に「あなたの姿 あなたの声は いつまでも私の思い出に」の部分が印象的でした。
  • 2の箇所の音楽的な魅力について解析していただきたいです。
回答を見る