プロが教える店舗&オフィスのセキュリティ対策術

「クラス型がの変数aがインスタンス化される際のメモリ上の動きについて」

メモリは、碁盤の目のようなかたちで存在しており、
int型やString型などの初期化の際には、値がそのままメモリの1つの目に入るという理解をしています。
ではクラスが型の変数aがインスタンス化される際、メモリ上でクラスの内容はどういう風に確保されているのでしょうか。
自身のイメージは以下の通りです。
① メモリ上に大きな範囲(複数の碁盤の目)を確保して、
  そこに型として用いるクラスの内容がコピーされる。
② 変数aがメモリ上にできる。
③ ①の先頭のアドレスが、aにコピーされる。
④ フィールドやメソッドが書かれると、変数aにアドレスを見に行って、
  そのアドレスにある①の内容が上書きされる。

以上の理解の間違い等を指摘していただけますとありがたいです。
よろしくお願いいたします。

A 回答 (6件)

純粋なオブジェクト指向の考え方なら、クラスはプログラムの実行時には一切かかわりません。


クラスはあくまでもコンパイルの時にのみ参照されるもので、その点では、マクロ定義みたいなものです。
(もっと厳密に言うなら、クラスは変数宣言の拡張、オブジェクトは変数の拡張)
JAVAはクラスのこの考え方を無視した変則的な使い方をしている傾向があるので、厳密にはJAVAはオブジェクト指向としては邪道です。
従って「メモリ上でクラスの内容はどういう風に確保されているのでしょうか」は
「メモリ上でオブジェクトの内容はどういう風に確保されているのでしょうか」と書くのが正しい。
「クラスの内容」-->「オブジェクトの内容」に変更しましょ。

コンパイラにてクラスに近い存在は構造体です。
通常の構造体はintやcharの変数の集まりですが、関数へののポインタも要素メンバーとして確保できます。
関数ポインタ持った構造体定義は、クラス定義と大差なくなります。

というわけで
構造体がメモリで確保されるしくみとオブジェクト(クラスではない)がメモリで確保されるしくみはほぼ同じです。
よろしいかな。
    • good
    • 0

String型みたいなデータ量があらかじめ決まっていないものは、た


いてい、別の領域に確保され、参照されることになると思います。

class Hoge
{
 Int32 I;
 String S;
}

のインスタンスが変数aに格納されている場合、

a.I = 123;

では、a本体の一部が上書きされますが、

a.S = "Fuga";

ということをやっても、参照先が変更されない限り、a本体は変わ
らないかもしれません。(言語の仕様によりけりですがね)
    • good
    • 0

メモリモデルは言語によっても変わるかと思いますが・・・


まず、メモリを碁盤の目で考えるのはあまり妥当ではないかと思います。
碁盤の目のような二次元的配置ではなく、一次元的な配置を考える方が少なくともノイマン形コンピュータや現在の一般的なプログラミング言語では妥当でしょう。

またオブジェクト(インスタンス)変数が全て参照型(変数にオブジェクトのアドレスを格納)とは限らず、埋込型(変数にオブジェクト自体を格納)の場合もあります。
C/C++ではポインタを指定しなければ通常は埋込型です。

あとオブジェクトのメモリ上への配置では、インスタンスごとに異なる情報はインスタンスごとに作成されますが、クラスで共通のメソッド(のプログラム)や定数は同じクラスのインスタンス全てで共有される場合もあります。
何を共有するかは言語モデルというより言語実装上の問題でしょうけど。
    • good
    • 0

C++ ならインスタンス自体を変数として保持することもできる.

    • good
    • 0

こんにちは


以下、私の理解を書いてみます。

例えば以下のクラスを考えます(文法は、いい加減なものです)
class MyClass {
  int x;
  int y;
  void SetX(int x){ this.x = x; }
  int GetX(){ return x; }
  // yについても同様なので省略
}
メンバ変数としてx,yを持ち、各々を読み書きするメソッドを持っているクラスです。


MyClass型の変数aの宣言
  MyClass a;     ①
インスタンスの生成
  a = new MyClass;  ②

①  メモリ上のどこかにMyClass型の変数aの領域が確保される
②-1 メモリ上のどこかにMyClass型インスタンスの領域が確保される
    内訳は、メンバ変数x,yの領域
    変数x,y各々の先頭アドレスはインスタンスの先頭アドレスからのオフセットで判断します。
    例えばint型が4バイトだとすると
    xの先頭アドレス = インスタンスの先頭アドレス + 0番地
    yの先頭アドレス = インスタンスの先頭アドレス + 4番地

②-2 ②-1で確保したインスタンスの領域の先頭アドレスが、変数aにセットされる。

ここで
 a.SetX(10); (aのメンバ変数xに10をセットする。)
が実行された場合は、

変数aの値(インスタンスの先頭アドレス)とxにセットする値(10)がパラメータとして、コンパイルされた実行ファイル内のMyClass.GetXのメソッドに対応する処理コードに渡されます。
そして、処理コードで、変数aが示すインスタンス領域の中の、メンバ変数xのオフセットである +0番地領域に値(10)がセットされます。
    • good
    • 0

特定の言語の話ではなくて、概念的な話で聞かれているとすると、


あまりメモリ上の動きを気にされなくてもよいように思うのですが、
実際のメモリ上といういみであれば、クラスの型の中身によるかと思いますが、
クラスの中の各変数なりは、クラスのコンストラクタで物理的なメモリとして確保することが多いと思うので、クラスを生成するときにドカンと大きなメモリが確保されるわけではないと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!