Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

純粋仮想関数が呼ばれてしまう場合

More than 3 years have passed since last update.

エラーだよねこれ

コンストラクタやデストラクタでクラスを指定せずに仮想関数を呼ぶのは最低でも警告、純粋仮想関数を呼ぶのはエラーにすべきだと思う。

新しい規格ではもうなっているのかも知れないけど完全に静的に判定できるのでC++11の時点でとっくになっていてもおかしくなかった内容だ。

その理由

vtableは他のメンバと同様に親から順に初期化されるので、親クラスのコンストラクタが走っている状態では一切オーバーライドされていない状態になっている。

ここで純粋仮想関数になっているメンバを呼んでしまうとvtableがオーバーライドされていないために純粋仮想関数が呼ばれてしまう...というのが機序。

ただの仮想関数の場合自クラス及び祖先クラスのメンバを呼ぶのは正当なのでクラスを指定することでエラーになる可能性を回避できるようになっている必要があるし無指定でも結果は安定なので警告でもよさそうだが、純粋仮想関数ではそもそも呼ぶ対象がないのでエラーにすべき。

またデストラクタでは逆順になるので純粋仮想関数でもvtableに値が入っているが、子クラスはすでにデストラクタが走ったあとなのでその呼び出しは無効だ。またただの仮想関数の場合でも子クラスのメンバが設定されている可能性が高いので指定がない場合はエラーにしていいと思う。

tarosuke@github
https://bitbucket.org/tarosuke とかでなんか作ってる。個人に関して詳しいことはGoogle+とかFacebookの方を参照しておくれ。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away