- ベストアンサー
継承したポインタ
まだ経験が浅いので単純な理屈だと思うのですが、納得できる資料がなかったのでどうかご教授お願いいたします。 class AAA { DATA *pData; }; class BBB : public AAA { ..... }; こんな感じのクラスを用意し、実体をメイン関数内で作ったんですが、 AAA aaa; BBB bbb; aaa.pData->Rendering(); これだと上手くいくのに bbb.pData->Rendering(); これだとアクセス違反になるのはなぜでしょうか?
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
>その核をBBBに渡して作り、Rendering()を実行すると上手くいったんですが、これ以降、このように担当を作るたびに核を渡していくという解決法で良いのかどうか悩むところです。 既に動かすことが目的になっていて、クラスを継承している意味が無いんです。オブジェクト指向の継承の理解が不十分だと思います。 オブジェクト指向的には、 aaa.pData->Rendering(); としていること自体間違いです。オブジェクト指向のカプセル化を理解できていません。 >AAAはシステムの起動から終了までの管理を行うクラスで、最初は描画やリソースetcもこいつに仕切らせようとしてましたが、描画内容などを定義するのは描画担当だけでいいという考え方で切り分けようと思いました。 描画担当であるBBBがシステム担当であるAAAを継承する必要はないですよね。それに、pDataを必要とするのはBBBだけでAAAには不要なのでは? このままで良いのかは本人に任せるとしても、オブジェクト指向とC++をちゃんと使いたいなら最低限カプセル化と継承の勉強をお勧めします。
その他の回答 (6)
- Tacosan
- ベストアンサー率23% (3656/15482)
「場所 0xcccccccc」ということからして, Visual C++ で初期化されていないポインタを使ったに 1票.
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
bbb.pDataがヘンなとこ指してるからでしょう。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
再現できません。どちらもアクセスできません。 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)
えーと コンストラクタの実装はどうなってますか? ロベールの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)
クラスの継承はプログラム構造とデータ構造だけを継承します。 それに対してデータは、クラスの変数を作るたびにそのインスタンス毎に領域が作られます。 AAA aaa; BBB bbb; と成っていたら、aaaとbbbは別のメモリ領域を持ちます。 aaa->pData; bbb->pData; はメモリ的に違う変数なのです。 ちなみに、 AAA aaaA; AAA aaaB; と成っていても、 aaaA->pData; aaaB->pData; はメモリ的に違う変数となります。
お礼
うむむ。 みなさんのおっしゃってることが把握しきれないのですが、おそらく中身がちゃんとしてない方のpDataを使ったからということでしょうか。 AAAはシステムの起動から終了までの管理を行うクラスで、最初は描画やリソースetcもこいつに仕切らせようとしてましたが、描画内容などを定義するのは描画担当だけでいいという考え方で切り分けようと思いました。AAAにあるシステムの核となるポインタ?からしかpData(描画担当)は作れないので、その核をBBBに渡して作り、Rendering()を実行すると上手くいったんですが、これ以降、このように担当を作るたびに核を渡していくという解決法で良いのかどうか悩むところです。 ともかくありがとうございました。
- buriburi3
- ベストアンサー率44% (353/792)
DATA *pDataがプライベートメンバーだから。 publicかprotectedメンバーなら派生クラスから参照できます。
お礼
回答ありがとうございます。 書き損じてすみません。そこは既にpublicにしてあります。 private メンバ にアクセスできません。 このような意味でのアクセス違反ではなく、 ハンドルされていない例外が発生しました: 0xC0000005: 場所 0xcccccccc を読み込み中にアクセス違反が発生しました。 このようなエラーが起きて困っている次第です。
お礼
みなさまの回答を参考に四苦八苦しながら、それぞれ担当ごとにクラスを分けて、なんとなくそれっぽい形でまとめることができたように思えます。確かに描画クラスが継承したらカプセル化を崩してしまっていますね。 もっと精進しようと思います。ありがとうございました。