usingを利用した継承関係でのオーバーロードのような処理

ロベールのC++入門講座 13-11

#include <iostream>

class CBase {
public:
    void func(int);
};

class CSub : public CBase {
public:
    void func(char*);
};

void CBase::func (int num) {
    std::cout << num << std::endl;
}

void CSub::func (char *str) {
    std::cout << str << std::endl;
}

int main () {
    CSub obj;
    obj.func("bar");
    obj.func(100);
    return 0;
}

この処理はコンパイルが通りません。「obj.func(100)」がエラーとなります。

CBaseのfunc(int)とCSubのfunc(char*)でオーバーロードが適用されそうに見えますが、継承をまたいだ場合はオーバーロードにならずに、関数の上書き、もしくはオーバーライド扱いになります。よってCSub型の変数objはfunc(char*)なので「obj.func(100)」がコンパイルエラーとなるわけなのです。

オーバーロードと継承 - (void*)Pないと

上記のように継承をまたいでのメンバ関数オーバーロードは基本的にはできません。

ですが、usingをうまく利用するとオーバーロードっぽいことが簡単に実現できます。

#include <iostream>

class CBase {
public:
    void func(int);
};

class CSub : public CBase {
public:
    void func(char*);

    // この一行を追加するだけ
    // これでCSubクラスにCBaseのfunc関数の全てにアクセスできるようにしてくれる
    using CBase::func;
};

void CBase::func (int num) {
    std::cout << num << std::endl;
}

void CSub::func (char *str) {
    std::cout << str << std::endl;
}

int main () {
    CSub obj;
    obj.func("bar");
    obj.func(100);
    return 0;
}
$ main
bar
100

かなり便利な機能ですね。使うケースがあるかもしれません。