无法从派生指针访问公共基础成员

时间:2012-05-31 16:37:22

标签: c++ inheritance polymorphism

为什么这段代码无法编译? (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)。我可以为我的代码使用各种变通方法,但我只是好奇为什么这段代码无法编译。

3 个答案:

答案 0 :(得分:11)

这就是语言的工作方式:当子类重写名称的成员时,它会隐藏父语句中所有未重写的名称。这是为了防止意外组合应该作为集重写的基本方法和父方法。

您可以将using Base::value;放入子类中以引入父方法。

答案 1 :(得分:3)

派生类中的函数value隐藏基类中的函数。

您需要将基类函数放在派生类的范围内:

class Derived : public Base {
public:

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

    void value (int Val) {
            // do some stuff here...
    }
};

答案 2 :(得分:2)

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

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

您明确告诉编译器使用Base的值函数。虽然从技术上说这是有效的,但它会强制一些间接性,如果你发现自己经常这样做,你可能想重新考虑如何构建你的代码。