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 回答
2

除了给出的其他答案之外,除了添加using Base::value子类之外,您还可以执行以下操作,

int x = instance->Base::value();

您在哪里特别告诉编译器使用Base's value 函数。尽管从技术上讲这是可行的,但它会产生一些间接性,如果您发现自己经常这样做,您可能需要重新考虑如何构建代码。

于 2018-04-19T15:52:37.513 回答