2017年12月25日
《その205》 抽象クラス(3)
抽象クラス
下記のプログラムでは、抽象クラス Aaa は3つの純粋仮想関数 set, get, func を持っています。
純粋仮想関数は、関数 set, 関数 get のように、関数本体を与えずに記述するのが一般的ですが、
関数 func のように関数本体を定義することも可能です(★1.と ★2.)。
関数 Aaa::func は、関数 set と 関数 get を連続して呼び出します。
純粋指定子「 = 0 」★1. を付ける都合上、関数定義をクラス定義の外に記述してあります★2.。
また、抽象クラス Aaa のデストラクタ ~Aaa ★3. は virtual の付いた仮想デストラクタになっています。
virtual無しの場合は、プログラム終了時に、デストラクタ ~Bbb が呼ばれず、 動的に確保 ★4. した領域が解放されないままになってしまいます。
// ------------------------------------
#include <iostream>
class Aaa {
public:
virtual ~Aaa() { // ★3.
std::cout << "~Aaa が呼ばれました。\n";
}
virtual void set() = 0;
virtual void get() const = 0;
virtual void func() = 0; // ★1.
};
void Aaa::func() { // ★2.
set(); get();
}
class Bbb : public Aaa{
int n;
int* p;
public:
Bbb(int x) : n(x) {
p = new int[n]; // ★4.
}
~Bbb() {
delete[] p;
std::cout << "~Bbb が呼ばれました。\n";
}
void set() {
for (int i = 0; i < n; i++)
p[i] = i;
}
void get() const {
for (int i = 0; i < n; i++)
std::cout << p[i] << " ";
std::cout << '\n';
}
void func() { Aaa::func(); }
};
int main() {
Aaa* p = new Bbb(5);
p->func();
delete p;
}
// ------------------------------------
もし、★3.の箇所で、デストラクタ ~Aaa に virtual が付いていない場合は、下のような結果になります。
デストラクタ ~Bbb が呼ばれていないことが確認できます。
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7129005
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック