4

このコードがコンパイルされないのはなぜですか? (gcc 4.7.0)

// Class with a simple getter/setter pair.
class Base {
public:
    Base () : m_Value(0) {  }

    virtual ~Base () {  }

    // Getter
    virtual int value () { return m_Value; }

    // Setter
    virtual void value (int Val) { m_Value = Val; }

private:
    int m_Value;
};

// Derived class overrides the setter.
class Derived : public Base {
public:
    void value (int Val) {
            // do some stuff here...
    }
};

int main()
{
    Derived * instance = new Derived();
    int x = instance->value();  // ERROR
    return 0;
}

ビルドログ:

test.cpp: In function 'int main()':
test.cpp:29:25: error: no matching function for call to 'Derived::value()'
test.cpp:29:25: note: candidate is:
test.cpp:21:7: note: virtual void Derived::value(int)
test.cpp:21:7: note:   candidate expects 1 argument, 0 provided

Derived* を使用しているときに、コンパイラが Base からの 'int value()' を認識できないのはなぜですか?

変化

Derived * instance = new Derived();

Base * instance = new Derived();

動作します(ただし、私の場合は派生ポインターが必要です)。

また、基本 getter/setter 関数の名前を getValue() および setValue(int) が機能するように変更します。コードに対してさまざまな回避策を使用できますが、このコードがコンパイルに失敗する理由が気になりました。

4

3 に答える 3

11

これが言語のしくみです。子クラスが名前のメンバーをオーバーライドすると、オーバーライドされていないすべての親の名前が隠されます。これは、セットとしてオーバーライドする必要がある基本メソッドと親メソッドを誤って組み合わせないようにするためです。

using Base::value;子クラスを配置して、親メソッドを取り込むことができます。

于 2012-05-31T16:40:46.313 に答える
3

value派生クラスの関数は、基本クラスの関数を隠します。

次のように、基本クラス関数を派生クラスのスコープに入れる必要があります。

class Derived : public Base {
public:

    using Base::value;   //<---- note this

    void value (int Val) {
            // do some stuff here...
    }
};
于 2012-05-31T16:41:02.203 に答える