C++では,構造体に「メンバ関数」というものを定義することができる. 例として,2次元のベクトルを考えてみよう.Cなら,こんな風に定義 するだろう.
struct vector2D {
int x;
int y;
};
デバッグのために,このベクトルを標準出力にプリントする関数を考えて
みよう.Cなら,こんな風に書くところだ.
void print2D(struct vector2D *v)
{
printf("(%d,%d)",v->x, v->y);
}
Cでは,他の構造体のprintと区別するため,例えばprint2D
のような名前にするだろう.
C++では,関数の多重定義があるので,もっと単純に
void print(vector2D *v)
{
printf("(%d,%d)",v->x, v->y);
}
でよい. struct vector2D {
int x;
int y;
void print() {
printf("(%d,%d)",x,y);
}
};
構造体のメンバとして,変数のほかに,構造体を扱う関数も
入れることができるというわけだ.これをメンバ関数という.
実際の構造体の中には,x, yのデータしか入っていないので,
メンバ関数をたくさん追加しても,構造体の大きさが大きくなる
心配はない.メンバ関数を使うときには,次のようにする.
vector2D v;
v.x = 10;
v.y = 12;
v.print();
構造体が変数に入っている場合は,
変数名.メンバ関数名(引数)のように呼び出す.構造体へのポインタが変数に入っているときには, もちろん
変数名->メンバ関数(引数)になる.
メンバ関数の定義のなかでは,構造体のタグであるxとか yを,あたかも普通の変数のように扱うことができる. (Pascalを知っている人なら,with文を想像するとよい.) また,メンバ関数の中では,今扱っている構造体へのポインタを, thisという特殊な変数で指定することができる.だから, 上の記述は
struct vector2D {
...
void print() {
printf("(%d,%d)",this->x,this->y);
}
};
と書いてもまったく同じだ.
複数のファイルで同じ構造体を使う場合,構造体の定義を ヘッダファイルに書く必要がある.その場合,メンバ関数はどうするのか というと,次のようにする.
ヘッダファイル
struct vector2D {
int x;
int y;
void print();
};
本文
void vector2D::print()
{
printf("(%d,%d)",x,y);
}
vector2D::printというのは,「vector2Dという構造体のメンバ であるprint」という意味だ.ヘッダファイルではメンバ関数の プロトタイプを宣言し,関数本体は別ファイルにするわけである. ただし,ヘッダファイルに関数本体を書いてもかまわない.この場合, ヘッダファイルに直接書かれた関数は,後述するインライン展開の対象 になる.