C 言語で、いくつかの変数をひとまとまりにしたものを構造体といいます。例えば、下のように struct を使って定義します。
typedef struct Item {
int code; /* 商品コード */
int name; /* 商品名 */
int price; /* 価格 */
} ITEM, *LPITEM ;
商品コードと商品名と価格を管理する場合、code, name, price の変数をそれそれ作るよりも商品( Item) でひとまとめすることでプログラムがわかりやすくなります。こういったまとまったデータをレコードともいいます。プログラムが小さいと大げさなように感じされますが、複雑になるにまし、struct のありがたみがわかります。
では C++ の構造体はというと、同じように使えます。C++ はCのソースコードをそのままコンパイルできるようになっています。ただし C++ のソースは C でコンパイル出来るとは無理なケースが多いです。
C++ は int, char, float などの基本型を除き、他すべてオブジェクトとして扱います。早い話は struct もオブジェクトなので class と同じように扱えます。
C/C++ ともに struct キーワード 同じなので、同じモノとして認識している人が多いようです。
また、オブジェクト指向の教科書の結構決まり文句で「クラスと構造体とは違う」と、書かれている時もあります。
C の構造体 != クラス
は、当たっていますが
C++ の構造体 = クラス
は、はずれです。細かく言うと
C++ の構造体 = C++ のクラス
です。
要するに class キーワードを struct キーワードを置き換えているのと変わりません。もちろん、コンパイルも通ります。
ただし class のデフォルトのアクセス修飾子が private になっているの対し、 struct のアクセス修飾子は public になっています。
| キーワード | メンバ関数 | デフォルトアクセス | 派生(継承) | 多様化 |
|---|---|---|---|---|
| struct (C) | 不可能 | public | 不可能 | 不可能 |
| struct (C++) | 可能 | public | 可能 | 可能 |
| class | 可能 | private | 可能 | 可能 |
| union (C) | 不可能 | public | 不可能 | 不可能 |
| union (C++) | 可能 | public | 不可能 | 不可能 |
C++ の構造体は派生も出来ます。あと 共有体 union ではメンバ関数を追加することまで可能です。
まぁ、百聞は一見にしかず。実際に使ってみましょう。コンパイルのテストは VC7.0 で行いました。
struct foo { /* foo 構造体 */
int s; /* public です */
public:
foo(){ /* constructor */
s = 3;
a = 1;
}
int geta() {return a;}
protected:
int a;
};
さて class と同じように書いてみました。意外とビックリするでしょう。では、次は派生してみましょう。
struct foo2 : public foo { /* foo を派生 */
foo2(){ /* constructor */
c = 'c';
}
char c;
char getc() {return c;}
};
構造体を派生するという、異様な光景です
さすがに、ここまでくると class と遜色がまったくないため逆に struct が間際らしいという欠点があります。
ちなみに下のように class に置き換えてもOKです。
class foo2 : public foo { /* foo を派生 */
foo2(){ /* constructor */
c = 'c';
}
char c;
char getc() {return c;}
};
特にありません(^^ゞ
こんな機能"も"あるんだよぐらいです。使っていると、構造体にメンバ関数がほしい時は、心おきなく付け足してあげてください。またコンストラクタが呼べるのでデフォルトで初期値が代入できるので便利です。
また、デストラクタで参照先のメモリを解放することも出来ます。ただし、そのときはコピーコンストラクタと代入演算子をオーバーロードしましょう。