C++で純粋仮想デストラクタが必要な理由とは?
純粋仮想デストラクタの必要性
C++プログラムにおいて、純粋仮想デストラクタを使用しても悪影響は一切ありません。むしろ、抽象クラスを作りたい場合に有効な手法の一つです。
ただし、純粋仮想デストラクタには関数本体(定義)を必ず提供する必要があります。その理由は、オブジェクト破棄の際に派生クラスのデストラクタが基底クラスのデストラクタよりも先に呼び出されるためです。もし関数本体を提供しないと、オブジェクトの破棄処理の中で基底クラスのデストラクタを呼び出そうとしたときに実体が存在せず、リンクエラーが発生してしまいます。
つまり、定義を持つ純粋仮想デストラクタを作成すれば、インスタンス化できない抽象クラスを簡単に実現できるのです。
サンプルコード
#include <iostream>
using namespace std;
class B {
public: virtual ~B()=0; // 純粋仮想デストラクタ
};
B::~B() {
cout << "Pure virtual destructor is called";
}
class D : public B {
public: ~D() {
cout << "~Derived\n";
}
};
int main() {
B *b = new D();
delete b;
return 0;
}出力結果
~Derived Pure virtual destructor is called
動作のポイント
このコードでは、delete b; の実行時にまず派生クラス D のデストラクタが呼び出され、その後、純粋仮想として宣言されている基底クラス B のデストラクタ本体が正しく実行されます。このように、純粋仮想デストラクタにもクラス外で定義を与えておくことで、ポリモーフィズムを利用した安全なオブジェクト破棄が可能になります。
-
C++の純粋関数とは?特徴とstrlen()・sqrt()を使った実装例をわかりやすく解説
純粋関数(Pure Function)とは、同じ引数の値に対して常に同じ結果を返す関数のことです。純粋関数は結果を返すだけにとどまり、引数の変更、入出力ストリームへのアクセス、出力生成といった余計な副作用(Side Effect)を一切持ちません。この性質により、純粋関数はプログラムの動作が予測しやすく、テストやデバッグ、並列処理においても扱いやすいという大きなメリットがあります。純粋関数と非純粋関数の例C++標準ライブラリには、純粋関数として振る舞うものが多数存在します。代表的な例としては以下のような関数が挙げられます。純粋関数の例: sin()、strlen()、sqrt()、max()、
-
C++のスコープ解決演算子(::)とは?必要性と使い方をわかりやすく解説
C++におけるスコープ解決演算子(::)は、変数のスコープによって隠されてしまった(見えなくなった)名前にアクセスするための演算子です。大きな特徴は、単項演算子としても二項演算子としても使えるという点にあります。 単項スコープ解決演算子:グローバル変数へのアクセス 名前空間スコープやグローバルスコープに存在する名前が、ブロック内やクラス内で同じ名前の宣言によって隠されている場合、単項のスコープ解決演算子を使えば、隠された元の名前にアクセスできます。 例えば、グローバル変数 my_var とローカル変数 my_var が同時に存在する状況を考えてみましょう。このとき、グローバル側の my_va