ページ 11

識別子の同じ純粋仮想関数で引数を取るものと取らないものがあった時2種類ともオーバーライドしなければならないか?

Posted: 2014年7月31日(木) 11:05
by てろっぷ
以前クラスに関する質問をした時はお世話になりました。
今回もクラスに関する質問をさせていただきます。

コード:

virtual int func() = 0;
virtual int func(int p) = 0;
上のように識別子の同じ二つの純粋仮想関数を定義し、ある派生クラスでは引数を取らない方を、別の派生クラスでは引数を取る方を使いたいと考えているのですが、この場合2種類ともオーバーライドしなければなりませんよね?

言語:C++
開発環境:Microsoft Visual Studio 2013

[hr]
オフトピック
皆さんテロップはこんな感じに水平線で区切って挿入しているのでしょうか?
それともランクアップすると入れられるようになる仕様とか?(素朴な疑問)

Re: 識別子の同じ純粋仮想関数で引数を取るものと取らないものがあった時2種類ともオーバーライドしなければならないか?

Posted: 2014年7月31日(木) 11:57
by YuO
当然,両方ともオーバーライドをしないといけません。

オーバーロードされた関数である以上,最終的には似たような動作を行うのが普通です。
オフトピック
典型例は,引数の一部が省略されていて,省略部分にはデフォルト値が設定されるような場合。
オーバーロードされた関数が全く異なる動作をするのであれば,そもそも別名をつけないと使う側が混乱します。
なので,全引数入りの純粋仮想関数を用意しておいて,残りの関数はデフォルトの設定としてその全引数入りの関数を呼ぶような作りにします。
こうすることで,通常は一つの仮想関数のオーバーライドで実装が済み,効率等の問題で特定の引数の組み合わせの場合だけ別のコードで実行したい,というようなことを処理できます。

コード:

class foo {
protected:
    virtual int funcImpl (int p1, const std::string & p2) = 0;
public:
    virtual int func () { return funcImpl(0, ""); }
    virtual int func (int p) { return funcImpl(p, "");}
    virtual int func (const std::string & p) { return funcImpl(0, p); }
};

Re: 識別子の同じ純粋仮想関数で引数を取るものと取らないものがあった時2種類ともオーバーライドしなければならないか?

Posted: 2014年7月31日(木) 18:14
by てろっぷ
返信遅れました。
成る程...やはりオーバーライドしなければならないと...
お、ご教示頂いたテクニックは面白いですね。
ただ無理にこう組むくらいなら普通に引数を取る関数を宣言すれば良いと思ったので、
つまり自分のプログラムでも初めからそうすればよかったってことですね...
YuOさん、回答ありがとうございました。勉強になりましたm(__)m