1. ホーム
  2. c++

[解決済み] c++のオーバーロードされた仮想関数はclangで警告されますか?

2023-06-03 17:56:17

質問

以下のコードをコンパイルする際、clangは警告を発します。

struct Base
{
    virtual void * get(char* e);
//    virtual void * get(char* e, int index);
};

struct Derived: public Base {
    virtual void * get(char* e, int index);
};

警告は

warning: 'Derived::get' hides overloaded virtual function [-Woverloaded-virtual]

(のようになります(もちろん、当該警告は有効にする必要があります)。

なぜなのか理解できません。Baseで同じ宣言をアンコメントすると、警告が停止することに注意してください。私の理解は、2つのget()関数が異なるシグネチャを持つので、隠蔽はありえないということです。

clang は正しいですか?なぜですか?

これはMacOS X上で、Xcodeの最近のバージョンを実行していることに注意してください。

clang --version
Apple LLVM version 5.0 (clang-500.1.74) (based on LLVM 3.3svn)

更新:Xcode 4.6.3でも同じ挙動です。

どのように解決するのですか?

この警告は、オーバーライドが意図されているときに、誤ってオーバーロードを隠してしまうことを防ぐためにあります。少し異なる例を考えてみましょう。

struct chart; // let's pretend this exists
struct Base
{
    virtual void* get(char* e);
};

struct Derived: public Base {
    virtual void* get(chart* e); // typo, we wanted to override the same function
};

警告である以上、必ずしも間違いであるとは言えませんが、間違いを示している可能性はあります。通常、このような警告には、より明確に、あなたが書いたものを意図していたことをコンパイラに知らせることで、それを遮断する手段があります。この場合、次のようにすればいいと思います。

struct Derived: public Base {
    using Base::get; // tell the compiler we want both the get from Base and ours
    virtual void * get(char* e, int index);
};