C++のオーバーロードとオーバーライドの挙動

C++のクラスで public なメンバ関数オーバーロードがある場合、派生クラスでオーバーロードのどれか一つを private でオーバーライドすると、他のオーバーロードも全て private になる。これは仮想関数であっても非仮想関数であっても同じ。

#include<stdio.h>

class BaseClass {
public:
    void hoge(int i) {
        printf("%d\n", i);
    }
    void hoge(int i, int j) {
        printf("%d, %d\n", i, j);
    }
};

class SubClass : public BaseClass {
private:
    void hoge(int i) {} // private でオーバーライド
};

int main(void)
{
    BaseClass base;
    base.hoge(1);
    base.hoge(1, 2);

    SubClass sub;
    sub.hoge(1);    // private でオーバーライドされたのでエラー
    sub.hoge(1, 2); // これも private になりエラー

    return 0;
}

これを回避するには、usingディレクティブを使う。

class SubClass : public BaseClass {
public:
    using BaseClass::hoge; // 基底クラスのhogeの使用を宣言
private:
    void hoge(int i) {} // private でオーバーライド
};

int main(void)
{
    BaseClass base;
    base.hoge(1);
    base.hoge(1, 2);

    SubClass sub;
    sub.hoge(1);    // private でオーバーライドされたのでエラー
    sub.hoge(1, 2); // これはOK

    return 0;
}

このようなことをする場面は少ないだろうが、基底クラスのpublic なメンバ関数オーバーロードの一部を派生クラスで無効にしたい場合に使える。