はじめに
まず、この記事は少しずれています
一生懸命よりよくするために勉強中なので少々お待ちください
ただし考え方の掴み方としては役に立つとは思います
こんにちは 高専1年生のメカテック部部員です
部活でいずれ使うということなので C++ の勉強も行っています
その時に生まれた一つの疑問点とその答えについて話したいと思います
まだまだ未熟な捉え方かもしれません
誤解があると教えていただけると幸いです
※ただしこれは自分を納得させるための考え方の一つにしかすぎませんので
参考までにお願いします
疑問点
クラスの重要点
C++ には一つの大切なクラスという概念があります
そして、クラスのメソッドを扱うためにはインスタンスを作る必要があります
インスタンスは
クラス名 クラスの変数名
と書いて作ることができるのは皆さんご存じの通りだと思いますが、
ここで一つの大事な要素があります
自動で行われるコンストラクタとデストラクタです
これらのことを今は
- 自動で呼ばれるコンストラクタ
- 自動で呼ばれるデストラクタ
と呼ぶことにします
※ただし勘違いしてほしくないのは、
コンストラクタやデストラクタの呼び出しの方法が他と違うだけで
コンストラクタやデストラクタ自体は同じものであるという点である
コンストラクタはインスタンスをobjとしてつくるときに呼ばれ、
デストラクタはインスタンスをobjとして削除するときに呼ばれます
newとdelete
インスタンスはもうメソッドを使わないと確定したときに
自動で呼ばれるデストラクタにより自動で消されます
それが好ましくないとき、newとdeleteをつかえば
好きな時にコンストラクタやデストラクタを行うことが可能となります
使用例)
クラス名 クラスの変数名 = new クラス名(引数)
delete クラスの変数名
これだけではエラーが出ます
それはなぜか? 考えてみてください
いったいなぜnewとdeleteの構文を使ったとたんに
コンストラクタやデストラクタが自動で呼び出されるということがなくなるのですか?
ところがインスタンスをポインタとして宣言すれば
コンストラクタやデストラクタが自動で行われるのを防ぐことができます
なぜ?今回はその問題に迫っていきます
スタックとヒープ
いきなり知らない言葉が出てわからなくなったと思いますが心配ありません
スタックやヒープのことをメモリ空間といいます
データ自体のことではありません
データの扱い方や保存法の構造のことです
実は、スタックには元からすでに使わなくなったobjを削除する機能があります
ヒープにそのような機能は備わっていないので
-
自動で呼ばれるコンストラクタ、デストラクタされるobjは
スタックのメモリ領域に、 -
newとdeleteによりコンストラクタ、デストラクタされるobjは
ヒープのメモリ領域に
置く必要があるのです
ポインタインスタンスとの関係
皆さんお気づきの通り、
ポインタインスタンスであるかどうかが
スタック、ヒープのどちらのメモリ領域を使うかを左右します
それはなぜでしょう
それはそれぞれのデータ構造のメモリの使用法に関係します
「スタックは後入先出のメモリ空間である」と聞いた人はいると思います
これはスタックのデータはメモリの順番にデータが入っていくことの象徴です
よってポインタによりアドレスを辿らずとも変数名によるアクセスだけでクラスのメソッドにたどり着くことができるのです
クラス名 クラスの変数名
それに対し、ヒープは効率のよいメモリ管理を行います
しかしその具体的な位置はプログラマには分かりません
だからポインタによってアドレスを辿る必要が生まれるのです
クラス名 *クラスの変数名
これより
これより、newとdeleteをつかった、
- インスタンスの生成
- コンストラクタ
- デストラクタ
これらの…
間違ったコード
クラス名 クラスの変数名
-
クラス名 クラスの変数名 = new クラス名(引数)
(宣言時に行う) デストラクタ名 クラスの変数名
正しいコード
クラス名 *クラスの変数名
-
クラス名 *クラスの変数名 = new クラス名(引数)
(宣言時に行う) デストラクタ名 クラスの変数名
最後に
ここまで読んでいただいてありがとうございました
C++の勉強の参考にしていただけると幸いです