C++:リファレンス、デリファレンス、ポインターを徹底解説

C++のポインター (pointer)、リファレンス(reference)、デリファレンス(dereference)は、C++初心者には理解するのがかなり困難です。ポインターを極めずしてC++を語るなかれとさえ言われている程で、C++入門者には鬼門となっているのが現状です。ちなみに、pointerは、ポインターともポインタとも言われているようなのですが、個人的にはポインターと言っています。ポインタだと。Ponta(ポンタ)のようなポイントの一種なのかな?と勘違いされそうだからです。

import ROOT
contents
スポンサーリンク

リファレンス (Reference)

リファレンスは、CPPReferenceで以下のように定義されています。

Declares a named variable as a reference, that is, an alias to an already->existing object or function.

名前付き変数を、リファレンス(参照)、つまり、既存のオブジェクトや関数のエイリアス(別名)として宣言する。何のことかよく分からないので、先ず、このリファレンスとは何なのかを見て行きます。

%%cpp

string str0 = "Trump";
string mystr = str0;

cout<<str0<<endl;
cout<<mystr<<endl;

mystr = "Donald";

cout<<str0<<endl;
cout<<mystr<<endl;
Trump
Trump
Trump
Donald

str0をTrumpと定義したので、当然、mystrもTrumpを返しますが、mystrの値を変えてもstr0の値は変わりませんでした。今度は、参照宣言子であるampersand(アンパサンド)&を付けてmystr1を参照型にしてみます。

%%cpp

string str1 = "Trump";
string& mystr1 = str1; //&を付けてmystr1を参照型にする

cout<<str1<<endl;
cout<<mystr1<<endl;

mystr1 = "Donald";

cout<<str1<<endl;
cout<<mystr1<<endl;
Trump
Trump
Donald
Donald

今度はmystr1の値を変えることでstr1の値も変わりました。&を付けてmystr1を参照型にすることで、mystr1がstr1になったということです。つまり、mystr1はstr1の別名ということになります。今度は関数の場合を検証してみます。

%%cpp -d

void str2 (string str)
{
   str += "Trump";
}

先ず、上記のようにstr2という関数を作ります。

%%cpp

string mystr = "Donald ";
str2(mystr);
cout <<mystr << endl;
Donald

pass by value(値渡し)だと、関数が機能していません。今度はpass by reference(参照渡し)で試してみます。

%%cpp -d

void str3 (string& str)
{
   str += "Trump";
}
%%cpp

string mystr = "Donald ";
str3(mystr);
cout <<mystr << endl;
Donald Trump

ちなみに、&は、参照宣言子としてではなく、address-of operator(アドレス演算子)としても使われます。&がアドレス演算子と言われる所以は、この演算子が以下の例のようにアドレスを参照するからです。

%%cpp

int i = 2;

cout<<i<<endl;
cout<<&i<<endl; //iの値が格納されているアドレスを表示
2
0x7f15fc364188
スポンサーリンク

ポインター(Pointer)

ポインタは一言で言えば、アドレスを格納している場所を指します。pointerという単語自体が指し示す物といったような意味合いになるので、感覚的に分かるかと思います。pointer = addressと言ってもいいかもしれません。

%%cpp

int i = 2;
int myptr = i;

cout<<i<<endl;
cout<<myptr<<endl;
2
2

pass by pointer(ポインター渡し)で、iのアドレスをmyptrに渡す場合にポインターが必要になります。これにはポインター宣言子のasterisk(アスタリスク)*を使います。

%%cpp

int i = 2;
int* myptr =& i; //asterisk*を使ってポインタ宣言する

cout<<i<<endl; 
cout<<myptr<<endl;
2
0x7f15fc3641b8

ポインターがアドレスを指し示す物であると言えることが分かるかと思います。autoを使うと以下の例のように自動的にポインタ宣言してくれます。

%%cpp

int a = 2;
auto b = &a;

cout<<a<<endl;
cout<<b<<endl;
2
0x7f15fc3641f8
スポンサーリンク

デリファレンス(Dereference)

デリファレンスはその名の通り、参照型から値型に戻すことを意味しています。これにはdereference operator(間接参照演算子)のasterisk(アスタリスク)*を使います。

%%cpp

int a = 2;
auto b = &a;

cout<<a<<endl;
cout<<b<<endl;
cout<<*b<<endl;
2
0x7f15fc364210
2

この間接参照演算子を使うと以下のようなこともできます。

%%cpp

int c, d;
int * myptr;

myptr = &c;
*myptr = 50;
myptr = &d;
*myptr = 100;
cout << "c is " <<c << '\n';
cout << "d is " << d << '\n';
c is 50
d is 100
スポンサーリンク
スポンサーリンク

コメント

タイトルとURLをコピーしました