category: C / C++
DATE : 2006/09/23 (Sat)
DATE : 2006/09/23 (Sat)
Java では、どこからも参照できなくなったオブジェクトはガーベジコレクタが検出してメモリを解放してくれます。C++ でも、以下のように宣言したオブジェクトは、スコープの終了とともに自動的に解放されます。
void func() { Point point; // 処理 }
しかし、動的に生成したオブジェクトは自分で破棄しなければなりません。
(;^ω^)「スマートポインタ」というものを使うと自動的に解放してくれるそうですが、今回は触れません。
動的に生成したオブジェクトを破棄するには、オブジェクトへのポインタに対して delete 演算子を使います。
Point* point = new Point; delete point;
C でのメモリの解放と同様に、解放済みのポインタに対して delete を行うと実行時にエラーが発生します。
ところで、動的に確保したオブジェクトがメンバ変数にある場合はどのように解放すれば良いのでしょうか。
ここで、 前回の記事の Point クラスを使って2次元座標上の線分を表す Line クラスを考えてみます。
Java で表現したコードは次の通りです。
public class Line { private final Point start; private final Point end; public Line(Point start, Point end) { this.start = start; this.end = end; } public Point getStart() { return this.start; } public Point getEnd() { return this.end; } }
(;^ω^)本当はコンストラクタの引数が null でないかどうかをチェックしないといけないのですが、ここでは省略しています。
C++ で表現すると次のようになります。
class Line { private : const Point *start; const Point *end; public : Line(const Point* start, const Point* end); ~Line(); const Point& getStart() const; const Point& getEnd() const; }; Line::Line(const Point* start, const Point* end) : start(start), end(end) { } Line::~Line() { delete this->start; delete this->end; } const Point& Line::getStart() const { return *(this->start); } const Point& Line::getEnd() const { return *(this->end); }
ここで、次の部分に注目してください。
~Line();
Line::~Line() { delete this->start; delete this->end; }
「~クラス名()」の形のメンバを「デストラクタ」と言い、そのクラスのオブジェクトが解放されるタイミングで呼び出されます。「解放されるタイミング」とは、前述にあるような、「スコープを外れた時」や「delete を行った時」のことです。
PR
●この記事にコメントする
忍者ブログ [PR]