前回は「オブジェクトを作成する時」に実行される「コンストラクタ」の仕組みについて学んでいきましたが、今回は「オブジェクトを削除する時」に実行される「デストラクタ」の仕組み等について見ていきたいと思います。
「どんな処理を書けばいいのか?」や「どのようにプログラムを書けばいいのか?」が全くわからないので、いろいろと調べながら勉強していきたいと思います。
「デストラクタ」の仕組み
「オブジェクト」を利用して不要になった際には、「確保したメモリ領域の解放」などの処理が必要なケースがあるとのことで、「オブジェクトを破棄」した際に実行できるのが「デストラクタ」というメソッドです。
名前が何か「物々しい」感じがしますが、担っている役割はいたってシンプルです。
「デストラクタ」を作るためには「クラス名」の前に「~(チルダ記号)」を付けることで、定義することができます。
~クラス名(){ // 必要な処理を書く }
形式的に引数を受けとる「()」がありますが、「デストラクタ」には引数は渡せないとのこと。だったら何で書く必要があるのかめっちゃ疑問・・・
まだ自分にはどういう風に使うのかあまりイメージはできないけれど、「オブジェクトのメンバ用に動的に確保したメモリ領域」を解放するのが主な利用方法のようです。
「インライン関数」とは?
クラスの中に関数を作った際に「関数呼び出しでは無く、処理がその部分に埋め込まれる」のが「インライン関数」なのですが、「関数の呼び出し」にかかる処理の負荷を低減できる機能のようです。
「インライン関数」を作るためには、関数を作る際に「戻り値のデータ型」の前に「inline」というキーワードを書くだけです。
inline 戻り値のデータ型 関数名(引数・・・){}
のようになり、呼び出される回数が多い関数ほど効果が大きいとのこと。
でも、関数の処理がそのまま埋め込まれたら関数の意味が無いんでは・・・
ただ、この挙動も「コンパイラ」によって変わるそうなので、「できたらやります」みたいな形らしい。
「inline」キーワードを書いても処理が埋め込まれないこともあるとのことで、「曖昧さ」がある機能に感じます。
「フレンド関数」って?
クラスのメンバに所属していない通常の関数が、「クラス内のメンバ」にアクセスができる関数を「フレンド関数」と言うそうです。
本来は「未公開メンバ」はそのクラスの関数しかアクセスができないのですが、この仕組みを使うことで、メンバ以外の関数から「メンバ」にアクセスすることができます。
「フレンド関数」を作るためには、そのクラスの先頭で「friend」キーワードを付けて宣言する必要があります。
ただ、クラスメンバの公開範囲が通常の公開範囲と異なるため、「利用非推奨」としているプロジェクトなどもあるそうで、「フレンド関数」を使う理由がある場合に限り、「局所限定的」に利用していく方が良さそうです。
静的メンバ
「クラスのオブジェクト」ではなく、「クラス」に「メンバ」を持たせることができる仕組みを「静的メンバ」というそうです。
初めにこの仕組みを聞いた時には全く意味がわからなかったのですが、これまでのクラスとオブジェクトの関係は、
のような形で、まず「クラス」を作り、そのクラスから「オブジェクト」を作るというものでした。
しかし、静的メンバの場合は、
のように「クラス」に「メンバ」が所属しているという形になるそうです。
ということは「オブジェクトと独立したデータ」が作れるということですね。
「静的メンバ」を作るのは簡単で、メンバの前に「static」キーワードを入れるだけで作ることができます。
プログラムを作ってみたいと思うのですが、今回は「3つのファイル」から構成されています。
- Sample.h
- 「Sampleクラス」のヘッダーファイル
- Sample.cpp
- 「Sampleクラス」の実装ファイル
- main.cpp
- 「main」関数が定義されているファイル
「ヘッダー」ファイルはクラスのメンバの「宣言」が書かれていて、具体的な内容は「実装」ファイルに書かれています。
「main.cpp」から「Sampleクラス」のヘッダーファイルを読み込み「Sampleクラス」を利用していきます。
それでは、まず「Sample.h」は、
#ifndef ___Class_Sample #define ___Class_Sample class Sample { public: static int count; }; #endif
のようになり、そして「Sample.cpp」は、
#include "Sample.h" int Sample::count;
となります。今回はメンバしか定義していませんが、「メンバ関数」を定義することもできます。
プログラムを実行するための「main.cpp」は、
#include <iostream> #include <string> #include "Sample.h" using namespace std; int main() { Sample::count = 0; cout << Sample::count << endl; return 0; }
のようになります。
「ヘッダーファイル」と「実装ファイル」を分けるという考え方は初めて触れたのですが、このようなファイル構成にしておくことで、「実装ファイル」をコンパイルし、外部から内容をわからないようにすることができます。
といっても、あまりよくわかっていないので、また改めて勉強したいと思います。
そろそろ「勉強疲れ」も出てきたのですが、まだまだたくさん学ばなくちゃいけないことがあるので、引き続き学習を進めていきたいと思います。
→(前へ)「カプセル化」とクラスへの「アクセス権限」について学ぼう!!