Cpp クラス thisポインタのソースを表示
新しいページはコチラ
移動:
案内
,
検索
<table class="mbox-small" style="border:1px solid #aaa; background-color:#f9f9f9; width:22em;" id="RealTitleBanner"> <tr> <td style="width:1px;"></td> <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++ クラス thisポインタ</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。</td> </tr> </table> ※このページでは[[C PlusPlus|C++]]にのみ存在する機能として、記事タイトルが<nowiki>C++ クラス thisポインタ</nowiki>になっています。<br /> <br /> == '''クラス thisポインタ''' == thisポインタとは、自分自身を指し示すポインタだと言われており、初心者が聴くとなんとなくワケがわからない教えられ方をあちらこちらでされているように見受けます。自分自身?それって何だ? その前に、thisというキーワードのポインタ変数が定義したクラスの中で、クラスを作成しただけで使える状態になっているということについては理解しなければならないです。そして、そのthisという名前のポインタ変数が何を示しているか? '''自分自身''' ポインタについての説明は[[C ポインタ]]に記述したので、あまり多くは語りません。ポインタについてイマイチまだわかっていないかもしれない。自分にはまだはやかったかもしれないと思った場合は読み返すか、他のサイトで調べるとかが必要になります。 thisっていう名前のポインタ変数が使えるようになっていることは、理解するというか、そういう仕様なんだから納得するしかないとして、自分自身っていう言われ方をするポインタ変数というのがどういうものなのかを示しておきたいと思います。 例えば、わかりやすい例で示せば、以下のような感じのプログラムを動かすことで自分自身という表現の意味を理解できるやもしれません。 ThisPointer001.h <syntaxhighlight lang="cpp" line start="1"> #pragma once class CThisPointer001 { public: CThisPointer001(void); ~CThisPointer001(void); }; </syntaxhighlight> ThisPointer001.cpp <syntaxhighlight lang="cpp" line start="1"> #include "stdafx.h" #include "ThisPointer001.h" CThisPointer001::CThisPointer001(void) { printf("this Address =%08x\n",this);//★1.thisポインタのアドレス出力 } CThisPointer001::~CThisPointer001(void) { } </syntaxhighlight> Sample_Main.cpp <syntaxhighlight lang="cpp" line start="1"> #include "stdafx.h" #include "ThisPointer001.h" int _tmain(int argc, _TCHAR* argv[]) { CThisPointer001* CThisPointer001_Instance = new CThisPointer001; printf("CThisPointer001_Instance Address=%08x\n",CThisPointer001_Instance);//★2.変数のアドレス出力 return 0; } </syntaxhighlight> またしても、サンプルが長くなってしまいましたが、辛抱強く試してみた人がいたとしたら、実行結果は以下のようになったでしょう。 出力結果 <syntaxhighlight lang="text"> this Address =00579108 CThisPointer001_Instance Address=00579108 </syntaxhighlight> ★1.と★2.でthisポインタの出力と生成したクラスオブジェクトの変数のアドレスが一致しました。これが自分自身ということの意味になります。だから?何ができるのか? 例えば、thisポインタを使って、メンバ関数やメンバ変数を呼び出すことができます。でも、thisポインタを使わなくても呼び出せていました。そしたらthisポインタってのは何の役に立つのか?それはですね。自分自身の中の何かのメンバ変数やメンバ関数であることを明示しなければならない場合があるということにつきます。たとえば[[Cpp クラス メンバ関数ポインタ|メンバ関数ポインタ]]で明示しなければならないパターンを示しました。 自動的に作られるthisというキーワードのポインタ変数は、意図的にthisポインタと同じものを作ることができます。 thisポインタと同じようなものを作るという意味で、プログラムを継ぎ足し変更したりして、以下のように変えてみます。 ThisPointer001.h <syntaxhighlight lang="cpp" line start="1"> #pragma once class CThisPointer001 { public: int mpub_nValue;//★1 CThisPointer001* this2;//★2 void mfpub_SetThis(CThisPointer001* pCThisPointer001_this);//★3 void mfpub_Output1(void);//★4 CThisPointer001(void); ~CThisPointer001(void); }; </syntaxhighlight> ThisPointer001.cpp <syntaxhighlight lang="cpp" line start="1"> #include "stdafx.h" #include "ThisPointer001.h" //★5 void CThisPointer001::mfpub_SetThis(CThisPointer001* pCThisPointer001_this){ printf("\n"); printf("■CThisPointer001::mfpub_SetThis\n"); printf("pCThisPointer001_this Address =%08x\n",pCThisPointer001_this); this2 = pCThisPointer001_this; printf("this Address =%08x\n",this); printf("this2 Address =%08x\n",this2); pCThisPointer001_this->mpub_nValue = 10;//★10. printf("mpub_nValue =%08d\n",mpub_nValue); this->mpub_nValue = 100;//★11. printf("mpub_nValue =%08d\n",mpub_nValue); mpub_nValue = 2000;//★12. printf("mpub_nValue =%08d\n",mpub_nValue); } //★6 void CThisPointer001::mfpub_Output1(){ printf("\n"); printf("■CThisPointer001::mfpub_Output1\n"); printf("this Address =%08x\n",this); printf("this2 Address =%08x\n",this2); printf("mpub_nValue =%08d\n",mpub_nValue); } CThisPointer001::CThisPointer001(void) { printf("\n"); printf("■CThisPointer001コンストラクタ\n"); printf("this Address =%08x\n",this); } CThisPointer001::~CThisPointer001(void) { } </syntaxhighlight> Sample_main.cpp <syntaxhighlight lang="cpp" line start="1"> #include "stdafx.h" #include "ThisPointer001.h" int _tmain(int argc, _TCHAR* argv[]) { CThisPointer001* CThisPointer001_Instance = new CThisPointer001; CThisPointer001_Instance->mfpub_SetThis(CThisPointer001_Instance);//★100 CThisPointer001_Instance->mfpub_Output1(); CThisPointer001_Instance->mpub_nValue = 1000; printf("\n"); printf("■Main\n"); printf("CThisPointer001_Instance Address=%08x\n",CThisPointer001_Instance); return 0; } </syntaxhighlight> そうすると、出力結果は以下のようになります。 <syntaxhighlight lang="text"> ■CThisPointer001コンストラクタ this Address =0094eeb8 ■CThisPointer001::mfpub_SetThis pCThisPointer001_this Address =0094eeb8 this Address =0094eeb8 this2 Address =0094eeb8 mpub_nValue =00000010 mpub_nValue =00000100 mpub_nValue =00002000 ■CThisPointer001::mfpub_Output1 this Address =0094eeb8 this2 Address =0094eeb8 mpub_nValue =00002000 ■Main CThisPointer001_Instance Address=0094eeb8 </syntaxhighlight> という具合です。 具体的に変更したところの中で重要なところはThisPointer001.hファイルの★1~★4を追加したこと、★5と★6のメンバ関数をプログラムとして追加したことです。 そして、特に確認しておきたいのは★5の関数の引数として、CThisPointer001クラスのメンバ関数の引数として、CThisPointer001クラスのポインタ変数を受け取ることになっている点です。このように自分で自分を受け取るみたいな形でポインタ変数を引数とすることにより、まさにthisポインタと同じようなものを作ったことになります。もちろん、呼び出すときにはメインプログラム側で、実体のある自分自身を引数に受け取らないと、自分自身を示すポインタは作れないので、メインプログラム側の★100のように自分自身を引数にするような組み込みが要求されます。 そうすると、★10のように pCThisPointer001_this->mpub_nValue = 10; というような★100で自分自身を受け渡したポインタ変数の中のメンバ変数への代入ができます。クラス内部からのアクセスなので、この代入はプライベートな領域のメンバ変数であっても呼び出すことが出来ます。その確認は自分自身にお任せしたいと思います。 これが自分自身ということになります。★11では、あえてthisポインタを明示したメンバ変数へのアクセス方法を記述しました。★10と同じことをしているというのは、最初のサンプルプログラムで、同じアドレスを保持していたことからも理解してもらえるものと思います。 ★12は従来というか、特に意識しなくても自分自身のメンバ変数にアクセスできていることがわかる部分になっています。 thisはポインタと同じようなものを作ったと書きましたが、やはり★12のように省略してもいいし、いつでもthisポインタは使えるという点では、全く同じものを作ることはできません。thisポインタはいつでも使えるという点においては、C++の仕様ですから、この便利さにかなうものもなければ、これと同じ役割のキーワードを新たに作ることも難しいでしょう。常にthisと同じ役割をする別名の変数を作るように動作させるマクロとか作れるのかもしれませんが、それができるかどうかについても自分自身で確かめていただければと思います。それが必要かどうか答えは自分自身で見つけて。 thisポインタが省略できるクラス内でのメンバ関数やメンバ変数の仕組みとかの原理や論理もあると思いますが、そのあたりは自分は理解していません。thisポインタの役割がわかっていれば、プログラムを読み解くことはできると思います。原理や論理を理解しないなんてバカだなぁと思う人はいるかもしれませんが、そういう人と関わるようになったときには積極的に理解していきたいと思います。そのときは優しく教えてくれるといいなぁ。この記事を読まれた若きプログラマは熱意をもって原理や論理にまで追求というか迫ると言うか、そういうようなことをしてもらったほうがいいのかもしれません。
テンプレート:記事名の制約
(
ソースを閲覧
)
Cpp クラス thisポインタ
に戻る。
個人用ツール
3.145.75.74
このIPアドレスのトーク
ログイン
名前空間
ページ
議論
変種
表示
閲覧
ソースを表示
履歴表示
操作
検索
案内
メインページ
コミュニティ・ポータル
最近の出来事
最近の更新
おまかせ表示
ヘルプ
ツールボックス
リンク元
関連ページの更新状況
特別ページ