Cpp クラス デストラクタ 新しいページはコチラ
提供: yonewiki
(→クラス デストラクタ) |
|||
5行: | 5行: | ||
<tr> | <tr> | ||
<td style="width:1px;"></td> | <td style="width:1px;"></td> | ||
− | <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++ クラス デストラクタ</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。</td> | + | <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++(Cpp) クラス デストラクタ</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。</td> |
</tr> | </tr> | ||
</table> | </table> | ||
19行: | 19行: | ||
− | ポインタ変数を定義した時点、図の★の部分では、char* pcA; | + | ポインタ変数を定義した時点、図の★の部分では、char* pcA;となっていて、図では、何もないchar型の大きさを知る穴あきの枠組プレートみたいなものが準備されます。この時点ではメモリ空間のポインタ変数がさすためのアドレス格納の旗みたいなものがあって、そこに32bitのメモリアドレスを保持できるのですが、最初は何も入っていない状態になります。旗があって枠がある。そんなイメージですね。図の中では間違えて16bitアドレスの場合と書いてますが、32bitが正しいです。そうするとアドレス範囲は0x00000000~0xffffffffで、この範囲の値が入る予定です。このアドレスを格納するアドレスだけは宣言した時点で決まります。それが図の例だと0x000100a0だとしています。これは &pcAとして取得できるモノです。実際には取得することはしないはずです。ポインタ変数にアドレス演算子を接頭句につけて使うことは、まずないでしょう。総じていうと、この時点でのpcAという変数は役立たずといってよいでしょう。変数を入れる領域についてのうつわ、箱、受け皿、そういったものすら用意できていないのです。変数を使うための準備はしたっていう感じです。指し示すことができるのは1byteの領域で基本charという型を指すことができて、そのアドレスを受け入れる枠だけは準備した状態です。中身はまだない。吾輩は猫である名前はまだない。そんな感じです。この状態のポインタ変数はヌルポインタと呼ばれます。 |
25行: | 25行: | ||
− | new演算子を使った場合は図のとおり、pcA = new char; と記述する処理を行います。これが、上向き矢印のところに書いた通り<span style = "background:linear-gradient(transparent 50%, #ff7f7f 50%); font-weight:bold; ">実体化</span>というモノにあたります。そうすると、またたくまに実際のメモリ空間に作用する処理が行われ、図の例の場合は1byte<span>(</span>8bit<span>)</span> | + | new演算子を使った場合は図のとおり、pcA = new char; と記述する処理を行います。これが、上向き矢印のところに書いた通り<span style = "background:linear-gradient(transparent 50%, #ff7f7f 50%); font-weight:bold; ">実体化</span>というモノにあたります。そうすると、またたくまに実際のメモリ空間に作用する処理が行われ、図の例の場合は1byte<span>(</span>8bit<span>)</span>のメモリ領域を確保し、確保した場所のアドレス0x0000ffa0がpcAに格納されます。図で言うと旗の部分です。旗の部分は実際のメモリ空間を使っていますから、どこか遠くのメモリ空間の先頭、この図の例では0x000100a0を先頭にここから32bitのところまでを使って、今回使うchar型アドレス pcA の0x0000ffa0が格納されます。メモリ空間の大きい値のところから手前に向かって32bitの値が格納される方式をWindowsでは扱っているため、図のようにひっくり返ったような感じで設定されます。これを<span style = "background:linear-gradient(transparent 50%, #ff7f7f 50%); font-weight:bold; ">リトルエンディアン方式</span>と言います。 |
− | + | 上記のような操作を行った結果、0x0000ffa0からの1byteがpcAが指し示すchar型の変数として、ただの枠だった、役立たずが、実体化をへて、実体を作りました。このようにして実体化されたものをまさに<span style = "background:linear-gradient(transparent 50%, #ff7f7f 50%); font-weight:bold; ">実体</span>とか<span style = "background:linear-gradient(transparent 50%, #ff7f7f 50%); font-weight:bold; ">Instance<span>(</span>インスタンス<span>)</span></span>と呼んでいます。インスタンスという聞きなれないかもしれないカタカナ言葉はこの先、かなり使う専門用語になります。プログラミングを続けるなら、この解説の文を読むなら覚えておくべきだと思います。 | |
− | + | ちなみにnewで実体化しようとして、メモリが足りないとかの理由で、何も指し示さない状態で、ポインタ変数の中身を参照しようとすると、エラーになります。ヌルポインタによるエラー(例外)が発生したと表現でき、専門用語で、ヌルポインターエクセプションと言います。エクセプションはexceptionという英語で日本語の意味としては例外という意味が有ります。こういった例外が発生しそうな処理に対して工夫をするのが例外処理というものですが、例外が発生しそうな時に行う処理の説明をすると長くなるので、別の記事で例外処理という項目を作る予定なので、そこでまた説明することにしましょう。 | |
+ | |||
+ | |||
+ | 話を戻すとして、このようなインスタンスに対して*pcA = 'A';のようにすると'A'のASCIIコード、SJIS、Unicode体系のUTF-8方式も同じですが、'A'のコード値の0x41が格納されます。リトルエンディアンなので、先頭から、0x1(b0001)、0x4(b0010)が格納されます。bから始まる数字は2進数0xは16進数で表現しています。リトルエンディアンなので2進数ビットも反転しますから、先頭から<span class="disable-auto-tel">1000 0100</span> と8bitが格納されます。 | ||
53行: | 56行: | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Ctest.h<span>)</span></span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Ctest.h<span>)</span></span><!-- padding 上 右 下 左--> | ||
<syntaxhighlight2 lang="cpp" line> | <syntaxhighlight2 lang="cpp" line> | ||
+ | #ifndef __CTEST_H_YONET__ | ||
+ | #define __CTEST_H_YONET__ | ||
class Ctest{ | class Ctest{ | ||
private: int* piValue; | private: int* piValue; | ||
− | private | + | private: int iArraySize; |
− | + | Ctest(int iArraySize); | |
− | + | ~Ctest(); | |
− | } | + | }; |
+ | #endif | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Ctest.cpp<span>)</span></span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Ctest.cpp<span>)</span></span><!-- padding 上 右 下 左--> | ||
<syntaxhighlight2 lang="cpp" line> | <syntaxhighlight2 lang="cpp" line> | ||
− | #include " | + | #include "ctest.h" |
− | + | Ctest::Ctest(int iArraySize){ | |
piValue = new int[iArraySize]; | piValue = new int[iArraySize]; | ||
} | } | ||
− | + | Ctest::~Ctest(){ | |
delete piValue; | delete piValue; | ||
} | } | ||
74行: | 80行: | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Destruct_Main.cpp<span>)</span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>Destruct_Main.cpp<span>)</span><!-- padding 上 右 下 左--> | ||
<syntaxhighlight2 lang="cpp" line> | <syntaxhighlight2 lang="cpp" line> | ||
+ | #include <cstdio> | ||
+ | #include "ctest.h" | ||
+ | |||
+ | using namespace std; | ||
int main(){ | int main(){ | ||
Ctest *pCtest; | Ctest *pCtest; | ||
84行: | 94行: | ||
delete pCtest; | delete pCtest; | ||
− | return | + | return true; |
} | } | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
90行: | 100行: | ||
== '''5行目''' == | == '''5行目''' == | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp<!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp<!-- padding 上 右 下 左--> | ||
− | <syntaxhighlight2 lang="cpp" | + | <syntaxhighlight2 lang="cpp" > |
− | + | Ctest::~Ctest(){ | |
− | + | delete piValue; | |
} | } | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
− | この部分がデストラクタと呼ばれる関数で、このクラスが消滅するときに必ず実行される関数です。呼び出し不要です。プログラムが終わったときに呼び出されることもあれば、Destruct_Main. | + | この部分がデストラクタと呼ばれる関数で、このクラスが消滅するときに必ず実行される関数です。呼び出し不要です。プログラムが終わったときに呼び出されることもあれば、Destruct_Main.cppの9行目のような、明示的なクラスの消滅処理でも呼び出されまます。 |
+ | |||
+ | |||
+ | コンストラクタと同じでクラス名と同じ名前関数で接頭句に~を付けて、~Ctestという具合の名前の関数を作ります。 | ||
メモリ解放処理に限らず、様々な用途にも使ってよいです。 | メモリ解放処理に限らず、様々な用途にも使ってよいです。 | ||
+ | |||
+ | |||
[[C PlusPlus#C++からの技術|C++]]に戻る | [[C PlusPlus#C++からの技術|C++]]に戻る |