人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

C++初心者です。
とんちんかんな質問をしていたらすみません。

A_file.cppとB_file.cppというファイルがあり、それぞれの中でAとBというクラスを定義していると仮定します。
このとき、クラスAのメンバ変数としてBのインスタンスを持たせる場合、ポインタとして定義する方法(以下ソースのmember_pointer_B)と実体を定義する方法(以下ソースのmember_B)があると思いますが、これらの違い(なぜこのような2つの方法があるのか、そもそも言ってることがおかしいとか、使い方が違うとか、メリット・デメリットとか)を教えて下さい。

// ソース
class A {
int numberA;
int numberAA;
B* member_pointer_B; // ポインタの定義
B member_B; // 実体の定義
}

宜しくお願い致します。

●質問者: konchan117
●カテゴリ:コンピュータ
✍キーワード:C++ Class すみません とんちんかん インスタンス
○ 状態 :終了
└ 回答数 : 6/6件

▽最新の回答へ

1 ● pernkopf
●23ポイント

なかなかツボをついた、いい質問ですね。

普通は、実体だけでいいじゃん、なんでポインタなんてものがあるの?と思うでしょうね。

まず、ポインタの第一特徴は、コストが安い(CPUの使用時間が短い)という事です。

メモリ上のアドレスを差してる過ぎませんから、わずか数バイトです。

これを参照したり、コピーするのは、実体に同様の操作を加えるのに比べて非常に高速です。

また、メモリも食いません。

ですので、ツボを押さえて使えば、非常に高速で軽いプログラムを作る事が出来ます。

じゃあ、実体はいらないじゃん、そう思うかもしれません。

実際、ほとんどの高級言語では、実体化ポインタかはコンパイラや処理系の内部で管理されていて、プログラムの段階でポインタと実体を意識する必要があるのは、CやC++に特徴的です。

しかしながら、ポインタには、非常に大きな、本質的な問題があります。

それは、メモリ上の具体的なアドレスを差しているため、どのスコープからアクセスしても同じ実体を差してしまっているのです。

昔のBasicのように、小規模で、オブジェクト志向でない言語であれば、それほど問題にはなりませんが、C++のように、厳密にスコープが定義され、その中では他にどんな変数や関数を使っているか全く意識されずにコーディングされる言語では、あるポインタの指す実体が、いったいどこからアクセスされる可能性があるのか把握する事は、非常に困難です。

言い換えると、ポインタを使用する際は、メモリ管理を明示的に行わないと、メモリリークが発生したり、あるいはアクセス違反が容易に発生指趾、致命的なエラーを起こしやすいのです。

そのため、処理速度やメモリを必要としないプログラムでは、処理系やコンパイラがメモリ管理を行ってくれる実体をそのまま使うのが、上記のような矛盾やエラーを回避するためには安全です。

ただし、やっぱり重いプログラムになりやすいです。

ここら辺は、安全とスピードのトレードオフとなります。

http://www.stackasterisk.jp/tech/program/c01_05.jsp

◎質問者からの返答

ありがとうございます。

実体での宣言と、ポインタでの宣言の違いが非常によくわかりました。

CとC++以外の言語を知らないので、勉強になりました。

ポインタにするか、実体にするかの判断基準がいまいちまだ理解できませんが、勉強します^^;


2 ● kurukuru-neko
●23ポイント

電話機A,Bがあるとすると

ポインターは、電話機を区別するBの電話番号

実体とは、電話機Bそのもののこと

実際には、

ポインターには、クラスが保存されているアドレスが記録され。

クラスには実体データとしてのint、ポインター、

その他データが保存される。


http://www.ybi.co.jp/koike/src/c.htm

http://homepage2.nifty.com/well/Class.html

◎質問者からの返答

ありがとうございます。


3 ● mark_hk
●22ポイント

○ポインタと実体を持つ違いですが、大いにあります。

これによってクラスのサイズが変わります。

※所有(含有)とアクセスの違いと捉えればいいのでは?

※メリット・デメリットというより構造上の違いなので、考えている構造にあわせれば良いのです。

◎質問者からの返答

ありがとうございます。

構造上での違いなのですね。

>ポインタ:アクセス用など所有していない場合

>実体:所有している場合(例えばパソコンクラスはメモリクラスを所有しているみたいな。わかりにくいか。)

こちらの説明はわかりやすかったです。ただポインタと実体の違いについてはわかっているつもりですが、それをどのような場面で使用するか?っていう判断基準っていうのでしょうか。。。それがまだ明確ではないのです^^;

例えばポインタで宣言しておいて、後からnewで領域確保する・・・という行為(知人がソース中で使っていたのですが)がどのようなことを示すのか(最初から実体を宣言するのとの違い?)が曖昧というか・・・。

自分でも自分が何を言いたいのかわからなくなってきたような気も^^;


4 ● mark_hk
●22ポイント

>例えばポインタで宣言しておいて、後からnewで領域確保する・・・という行為(知人がソース中で使っていたのですが)がどのようなことを示すのか(最初から実体を宣言するのとの違い?)が曖昧というか・・・。


上の点については、

  1. ポインタが必然の場合
  2. 仮想関数が関係している場合

があるのかなと思います。


「ポインタが必然の場合」

使用しない場合はNULLポインタのままで、使用する場合に実体を作成するということをしている。(もしくは、宣言の時点では実体が決められない。プログラムの状況によって初めて決められるようになる。)


「仮想関数が関係している場合」

このURLを見てみると、Baseクラスのポインタの配列があるのですが、実体はBaseクラスから派生した、Point1クラスとPoint2クラスだったりするわけです。仮想関数であるshow_color関数を呼ぶことによってBaseクラスのポインタにアクセスしているのに、Point1クラスとPoint2クラスの関数を呼ぶことができます。


※説明が分かりづらいかもしれませんが、いかがでしょうか?

◎質問者からの返答

ありがとうございます。

仮想関数・・・まだ勉強中なので、よくわかっていませんが、これから勉強します^^;


5 ● pernkopf
●10ポイント

ポインタと実体のメリットデメリットは、実際のところ自分である程度プログラミングしてみないと、体感しづらいと思います。

最初は自分で1から作るのではなくて、人のコードで理解できる部分を改変しながらその出力の変化を見ていくのがいいと思います。

最近のPCは非常に高速かつ大容量なので、ある程度大規模なコードでない土佐がわかりにくいかもしれませんが…。

言語の定義を全て理解しようとすると、頓座しやすいと思います。

特に、ポインタは、メモリを直接アセンブリ言語などで管理したことがないと、意味がわかりにくいです。

まずは、やってみる、のがよろしいかと。


1-5件表示/6件
4.前の5件|次5件6.
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ