オブジェクトポインタ
オブジェクトのアドレス
C言語を熟知している方ならば、ポインタは手足のように扱えるはずです
構造体や共用体、関数にメモリアドレスが存在するように
当然オブジェクトにもアドレスが存在します
オブジェクトのポインタの宣言、代入方法などは
やはり構造体とほとんど同じです
class-name *po;
po = &obj;
class-nameにはクラス型を、
objには、ポインタに代入するオブジェクトを指定します
オブジェクトのポインタにアドレスを代入するのにも、&演算子を用います
オブジェクトのポインタからメンバ変数や関数にアクセスするには
これも構造体同様にアロー演算子 ( -> )を使用します
po->member;
当然、オブジェクトのポインタとオブジェクトは同じアドレスを指しています
オブジェクトが破棄されれば、そのポインタも保証されなくなります
#include <iostream>
using namespace std;
class Kitty {
public:
char *str;
} obj ;
int main() {
obj.str = "Di_Gi_Gharat";
Kitty *po = &obj;
po->str = "Kitty on your lap";
cout << obj.str;
return 0;
}
po->str でポインタからメンバ変数にアクセスしています
ポインタから文字列を代入したため、最後に obj.str で出力する文字列は Kitty on your lap になります
さて、ポインタはメモリアドレスを表す以外にもう一つの魅力がありました
C言語の特権の一つアドレスの演算です
オブジェクトのポインタ po をインクリメントすると
オブジェクトのサイズだけ移動させた次のメモリアドレスを指すことになります
通常、オブジェクトのポインタを演算するようなことはありません
しかし思い出してください、ポインタの演算は物理的に並んだデータに非常に有効でした
物理的に並んだデータとは、すなわちオブジェクトの配列です
ポインタでは、obj[0]を表す po ポインタがある時
(po + 1) を指定することで obj[1] を表すことができるのです
#include <iostream>
using namespace std;
class Kitty {
public:
char *str;
Kitty(char *);
};
Kitty::Kitty(char *str) {
Kitty::str = str;
}
int main() {
Kitty *po , obj[2] = { "Kitty on your lap\n" , "Di_Gi_Gharat\n" };
po = &obj[0];
cout << po->str;
cout << (po + 1)->str;
return 0;
}
cout << (po + 1)->str; に注目してください
このポインタが指すメモリアドレスは obj[1] に等しいのです
オブジェクト型のポインタ変数のインクリメントも、そのオブジェクトのサイズだけ移動します
C言語の経験者であれば、この点も理解は簡単ですね