継承時にスーパークラスに仮想関数をつける理由

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
agunesu

継承時にスーパークラスに仮想関数をつける理由

#1

投稿記事 by agunesu » 5年前

なぜデストラクタだけが仮想関数をつけなければ、サブクラスのデストラクタが発動しないのか。(オーバーライドしていないのになぜ?)
どなたかわかりやすい説明をお願いします(´;ω;`)

agunesu

Re: 継承時にスーパークラスに仮想関数をつける理由

#2

投稿記事 by agunesu » 5年前

agunesu さんが書きました:
5年前
なぜデストラクタは仮想関数をつけなければ、サブクラスのデストラクタが発動しないのか。(コンストラクタには不要で、オーバーライドしていないのになぜ?)
どなたかわかりやすい説明をお願いします(´;ω;`)

かずま

Re: 継承時にスーパークラスに仮想関数をつける理由

#3

投稿記事 by かずま » 5年前

質問が不明確なので確認します。
プログラミング言語は C++ ですか?

スーパークラス、サブクラスという名称は Java の用語です。
C++ では、基底クラス、派生クラスという用語が一般的です。
C++ の規格書ににもそう書かれています。まあ、親クラス、
子クラスなどということもあるので意味は分かります。

「仮想関数をつける」というのが不明確です。
おそらく
「メンバ関数に virtual を付けると仮想関数になる」
または、
「virtual のついたメンバ関数は仮想関数である」
ということなのでしょう。クラスにおいて、
コンストラクタやデストラクタは特殊なメンバ関数です。

「デストラクタが発動する」というのも
クラスのインスタンス(オブジェクト)解体時に
デストラクタが自動的に呼び出されるという意味なんでしょうね。

質問を上手く書けない時は、サンプルコードを書き添えることを
お勧めします。

コード:

#include <stdio.h>

struct Base {
	Base() { puts("Base()"); }
	virtual ~Base() { puts("~Base()"); }  // ★
};

struct Derived : public Base {
	Derived() { puts("Derived()"); }
	~Derived() { puts("~Derived()"); }
};

int main()
{
	Base *p = new Derived();
	delete p;
}
実行結果

コード:

Base()
Derived()
~Derived()
~Base()
★の行で virtual がないときの実行結果

コード:

Base()
Derived()
~Base()
質問は、「基底クラスのデストラクタに virtual を付けないと
派生クラスのデストラクタが呼び出されないのはなぜですか?」
ということですね。
回答は、「それが、C++ の言語仕様だから」としか言えません。

new Derived() でオブジェクトを生成しているので
コンストラクタの Base() も Derived() も呼び出されます。
delete p でそのオブジェクトを解体しようとすると、
p が Baseクラスへのポインタなので、~Base() が呼び出されます。
デストラクタに virtual がついていると、~Base() の呼出しの前に
~Derived() が 呼び出されます。
派生クラスのデストラクタと、基底クラスのデストラクタの両方が
呼び出されるということです。

デストラクタではなく、通常のメンバ関数の場合は、少し異なります。
virtual がないと、基底クラスのメンバ関数だけの呼び出しになり、
virtual があると、派生クラスのメンバ関数だけの呼び出しになります。
virtual があっても、「p->Base::メンバ関数()」と書けば、
基底クラスのメンバ関数を呼び出せます。

以上、分かりやすい説明だったでしょうか?
分かった場合も分からない場合も返信をお願いいたします。

agunesu

Re: 継承時にスーパークラスに仮想関数をつける理由

#4

投稿記事 by agunesu » 5年前

大変わかりやすい説明ありがとうございましたm(_ _)m
自分が説明不十分だったのに的確の説明でした(笑)
今度からもっと詳しく書き込みたいと思います。
どうもありがとうございました<(_ _)>

agunesu

Re: 継承時にスーパークラスに仮想関数をつける理由

#5

投稿記事 by agunesu » 5年前

大変わかりやすい説明ありがとうございましたm(_ _)m
自分が説明不十分だったのに的確の説明でした(笑)
今度からもっと詳しく書き込みたいと思います。
どうもありがとうございました<(_ _)>

返信

“C言語何でも質問掲示板” へ戻る