メインコンテンツ

オーバーロードされたバーチャル関数の一部のみをオーバーライドします

特定名をもつ継承されたバーチャル関数の一部をクラスがオーバーライド

説明

この欠陥は、以下の場合に発生します。

  • 基底クラスに、名前が同じでシグネチャが異なる複数の virtual メソッドがある (オーバーロード)。

  • 基底クラスから派生したクラスが、それら virtual メソッドの少なくとも 1 つをオーバーライドしているが、すべてをオーバーライドしてはいない。

リスク

派生クラスがオーバーライドしていない virtual メソッドは隠されています。そうしたメソッドを、派生クラスのオブジェクトを使用して呼び出すことはできません。

修正方法

基底クラスでのオーバーロードが必要かどうかを確認します。必要である場合は、次のような解決法があります。

  • 派生クラスで 1 つの virtual メソッドがオーバーライドされている場合は、そのメソッドと同じ名前をもつ、基底クラスからのすべての virtual メソッドをオーバーライドします。

  • それ以外の場合は、派生クラスの宣言に using Base_class_name::method_name という行を追加します。この方法により、基底クラスのメソッドを派生クラスのオブジェクトを使用して呼び出すことができます。

すべて展開する

class Base {
public:
    explicit Base(int b);
    virtual ~Base() {};
    virtual void set()           {
        _b = (int)0;
    };
    virtual void set(short i)    {
        _b = (int)i;
    };
    virtual void set(int i)      {
        _b = (int)i;
    };
    virtual void set(long i)     {
        _b = (int)i;
    };
    virtual void set(float i)    {
        _b = (int)i;
    };
    virtual void set(double i)   {
        _b = (int)i;
    };
private:
    int _b;
};

class Derived: public Base {             
        public:
                Derived(int b, int d): Base(b), _d(d) {};
                void set(int i)    { Base::set(i); _d = (int)i; };
        private:
                int _d;
};

この例では、クラス Derived が、引数 int を取る関数 set をオーバーライドします。set という同じ名前をもち他のタイプの引数を取る他の関数はオーバーライドしません。

欠陥は、派生クラス定義の派生クラス名に表示されます。どの基底クラス メソッドがオーバーライドされているかを探るには、次のようにします。

  1. 基底クラス定義に移動します。[ソース] ペインで、基底クラス名を右クリックして [定義に移動] を選択します。

  2. 基底クラス定義で、派生クラスのメソッド名と同じ名前とシグネチャをもつメソッドを特定します。

修正 — 基底クラスのメソッドが隠れないようにする

1 つの修正方法として、using Base::set という行を Derived のクラス宣言に追加します。

class Base {
public:
    explicit Base(int b);
    virtual ~Base() {};
    virtual void set()           {
        _b = (int)0;
    };
    virtual void set(short i)    {
        _b = (int)i;
    };
    virtual void set(int i)      {
        _b = (int)i;
    };
    virtual void set(long i)     {
        _b = (int)i;
    };
    virtual void set(float i)    {
        _b = (int)i;
    };
    virtual void set(double i)   {
        _b = (int)i;
    };
private:
    int _b;
};

class Derived: public Base {             
        public:
                Derived(int b, int d): Base(b), _d(d) {};
                using Base::set;
                void set(int i)    { Base::set(i); _d = (int)i; };
        private:
                int _d;
};

結果情報

グループ: オブジェクト指向
言語: C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: PARTIAL_OVERRIDE
影響度: Medium

バージョン履歴

R2015b で導入