ページ 11

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

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

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

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

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

Posted: 2019年3月25日(月) 02:50
by かずま
質問が不明確なので確認します。
プログラミング言語は 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::メンバ関数()」と書けば、
基底クラスのメンバ関数を呼び出せます。

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

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

Posted: 2019年3月26日(火) 15:21
by agunesu
大変わかりやすい説明ありがとうございましたm(_ _)m
自分が説明不十分だったのに的確の説明でした(笑)
今度からもっと詳しく書き込みたいと思います。
どうもありがとうございました<(_ _)>

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

Posted: 2019年3月26日(火) 15:22
by agunesu
大変わかりやすい説明ありがとうございましたm(_ _)m
自分が説明不十分だったのに的確の説明でした(笑)
今度からもっと詳しく書き込みたいと思います。
どうもありがとうございました<(_ _)>