第十三回-03 ドット演算子とアロー演算子

例えば int 型に通常の変数とポインタ変数があったように、クラスにも通常の変数とポインタ変数とが存在する。
クラスにおいてポインタの利用は避けられない事が多い。

本ページではそのために必要な知識を学ぶ。

テレビクラスをポインタ変数で利用してみよう

main 関数における実際の使用例がこちら。第十三回-01とやっていることはほとんど変わらない。



コピーペーストできる形式での表示は以下の通り。

#include "Television.h"

int main(int argc, char* argv[])
{
	Television *tvp;  // テレビクラスのポインタの宣言

	tvp = new Television(); // テレビクラスのオブジェクトをヒープ領域に確保
							// これにより、ポインタの指す先が決まる。
							// ここでコンストラクタが呼ばれる

	tvp->printStatus();

	tvp->setPower(1);
	tvp->setChannel(8);
	tvp->setVolume(10);

	tvp->printStatus();

	delete tvp;  // new で確保したオブジェクトは delete で解放

	return 0;
}

さて、やっていることは第十三回-01とほとんど変わらないのだが、
よくよく見ると記述が微妙に異なる。順に見て行こう。

まず、ポインタ変数の宣言が以下である。これは int 型など通常の型に対するポインタ変数と同様で、アスタリスク ( * ) をつければよい。 次に、ポインタに対して新たなメモリ領域を確保してオブジェクトを生成している行 がある。これは第十一回「new 演算子によるメモリの動的確保」 に類似しているので復習しておこう。
これにより、下図のようにヒープ領域にオブジェクトが確保され、ポインタ tvp はそちらを指すようになる。
通常の変数 tv の場合との違いに注意しよう。



そして、メンバ関数の呼び出し。ここが一番目立つ違いであろう。 ポインタ変数からのメンバ関数の呼び出しは、このようにドット演算子 ( . ) ではなく
アロー演算子 ( -> ) を用いる。これは、上のメモリの模式図を想像するとイメージしやすいかも知れない。

そして最後に、new で確保したメモリは delete で解放する。これは第十一回「new 演算子によるメモリの動的確保」 に類似しているので復習しておこう。 このように、C++ では変数からのメンバ関数呼び出しはドット演算子、 ポインタからのメンバ関数呼び出しはアロー演算子、と使い分ける
のが特徴であり、後に登場した Java や C# に比べると繁雑なところである。

Java や C# ではメンバ関数の呼び出しは全てドット演算子で統一されている。
なお、Java や C# でのクラス変数は全て内部的にはポインタのような振舞いをするので、
new でメモリ確保する点など、利用法はむしろ C++ でのポインタに似ている。

最後に int などの型とクラスとで、通常の変数とポインタ変数の利用法の違いを整理しておこう。

宣言 アドレス
通常の変数 int x x &x
ポインタ変数 int *x *x x


宣言 実体 アドレス メンバ関数呼び出し
通常の変数 Television t t &t t.func()
ポインタ変数 Television *t *t t t->func()




←第十三回-02 何故クラスを使うのか?第十三回課題→

非情報系学生のための C/C++ 入門に戻る