パソコン活用研究シリコンバレー(C、C++、の活用研究)

クラス、オブジェクト、インスタンス
(準備中)
=========================================================================================
オブジェクト指向のプログラミング言語の代表格であるC++とJavaで、クラス、オブジェクト、インスタンスの意味合い、
動作が少し違ったりするので、C++のクラス、オブジェクト、インスタンスの確認
==========================================================================================

C++のクラス、オブジェクト、インスタンス

C++の書籍、Web上の解説で、クラス、オブジェクト、インスタンスについていろいろな説明がありますが、
なんだかわかりにくいですよね。
クラスは金型で、インスタンスはその金型から作られた実体だ、みたいな説明があったりするわけですが、
初めてオブジェクト指向のプログラミングをする時に、金型とか実体とか言われると余計混乱しそうです。
ということで、その意味するところを実際のプログラムと照らし合わせながらみてみたいと思います。

ある書籍には、
@クラスはオブジェクトを定義する型である。
Aクラスの型によって変数を宣言することで、クラスはメモリ上に実体を持つ。
 この実体のことをインスタンスと呼ぶ。
Bオブジェクトとはクラスのインスタンスのことである。
とあります。

確かに、この説明の通りなのかもしれませんが、抽象的でわからないです。
日本語にするより、英英辞典の定義で考えたほうがなんとなく理解しやすいかもしれません

まず、クラスとは何?
a group of things that have similar characteristics (Oxford 現代英英辞典)

よく、インスタンスを作ると言いますが、instanceとは何か。
a paticular example (Oxford 現代英英辞典)
典型例ということのようです。

で、objectは
a thsing that can be seen and touched (Oxford 現代英英辞典)


なんか、同じような機能、特徴をもったグループを定義したもの。これがクラスといわれるものらしい。
そして、その同じ機能をもった個々の実例(典型例)がインスタンスであり、インスタンスとはオブジェクトなので、
見たり触れたりすることができるものだ、ということになる。

・すなわち、クラスは定義であり、見たり触れたりはできない。
・インスタンス(=オブジェクト)は見たり触れたりできる。
ということらしい。

ここで、見たり触れたりできるというのは、メモリ上(データ領域やヒープ領域)に展開されていて、プログラムでアクセス
できるという意味になる。

とか、だらだら説明書いてみるより、プログラムで試したほうが早いので、プログラムを作ってみます。

最初に、Cの構造体で試してみます。
@ starという構造体を定義。 (「クラスはオブジェクトを定義する型である」に該当する部分)
A 構造体starの変数としてstを宣言します。(クラスの型によって変数を宣言することで、クラスはメモリ上に実体を持つ)
(a)構造体名starでアクセス

<struct.c>

#include <stdio.h>
/* @ */
struct star{
int x;
int y;
};

int main(void) {
struct star st; /* A */
st.x=1; st.y=2;
star.x=3; star.y=4; /* (a) 未定義のシンボルエラーになる */
printf("%d,%d",st.x,st.y);
return 0;
}


Borland C++5.5.1でコンパイルしてみます。

c:\bcc55\Bin>bcc32 struct.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
struct.c:
エラー E2451 struct.c 11: 未定義のシンボル star(関数 main )
*** 1 errors in Compile ***

Aのstruct star st; 
という宣言で構造体starは、変数stとしてメモリ上に領域を確保しプログラムからアクセスできるようになった。
=オブジェクトとして実体を持った = 構造体structのインスタンスが生成された

(a)のように構造体名starでアクセスしようとするとエラーになる。
=構造体の定義はメモリに展開されない(実体を持たない) 

というように解釈してもいいように思います。


では、C++のクラスで。
クラスとはいっても、上記の構造体と中身は同じです。
@ クラスstarの定義
A クラスstarの変数としてstを宣言 (ここでメモリに展開され変数stの領域が確保される)
(a) クラス名のstarでアクセスしてみる。
<class.cpp>

#include <stdio.h>
/* @ */
class star{
public:
int x;
int y;
};

int main(void) {
star st; /* A */
st.x=1; st.y=2;
star.x=3; star.y=4; /* (a) エラーになる*/
printf("%d,%d",st.x,st.y);
return 0;
}

コンパイルしてみると、上記構造体の場合(struct.c)と同じく、クラス名でのアクセスはできない。

c:\bcc55\Bin>bcc32 class.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
class.cpp:
エラー E2108 class.cpp 12: typedef 'star' の使い方が間違っている(関数 main() )
エラー E2108 class.cpp 12: typedef 'star' の使い方が間違っている(関数 main() )
*** 2 errors in Compile ***


A star st; という宣言によってクラスstarはメモリに展開され(オブジェクト化され =実体を持ち
=インスタンスが生成)、プログラムからアクセス可能になる。

(a) クラス名starはメモリに展開されない(実体をもたない)のでアクセスできない。


ということで、C++で言うところのクラス、オブジェクト、インスタンスはそれぞれこういうことのようです。


ついでに、Javaのクラス、オブジェクト、インスタンスのお話。
Javaでも書籍には
・クラスは概念
・オブジェクトは実体
・クラスから作ったインスタンスはオブジェクト
などと書かれており、なんだC++と同じじゃんと思うかもしれませんが、1点違いがあります。

Javaではクラスも実体を持つ(=オブジェクトになる)という点がC++と異なります。
察しがいい方は、ということは、Javaのクラスはプログラムからアクセスできるのかと思われるでしょうが、
その通りなんです。


javaではインスタンスを作らなくてもクラスのメンバーにアクセスできてしまいます。
以下のプログラムでは、Teststar.javaのほうから、クラスStarの変数を直接アクセスしています。
このようにJavaはクラスがメモリ上に展開されており、修飾子staticを付けた変数には、直接アクセスできるように
なっています。


<Star.java>
public class Star {
static int x=1;
static int y=2;
}

<Teststar.java>
import java.io.*;

public class Teststar {
public static void main(String[] args) {
System.out.println(Star.x);
System.out.println(Star.y); }
}


以下、コンパイルして実行
Teststar.javaをコンパイルすると、そこから参照しているStar.javaも自動的にコンパイルされます。

c:\java>javac Teststar.java

c:\java>java Teststar
1
2


ちなみに、C++の修飾子staticはJavaとは機能が異なり、変数のスコープの問題になります。



TopPage