【问题标题】:Can't access public base member from derived pointer无法从派生指针访问公共基成员
【发布时间】:2012-05-31 16:37:22
【问题描述】:

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

【问题讨论】:

标签: c++ inheritance polymorphism


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    您需要将基类函数带入派生类的范围内:

    class Derived : public Base {
    public:
    
        using Base::value;   //<---- note this
    
        void value (int Val) {
                // do some stuff here...
        }
    };
    

    【讨论】:

      【解决方案3】:

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

      int x = instance-&gt;Base::value();

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

      【讨论】:

        猜你喜欢
        • 2011-01-27
        • 2016-07-31
        • 1970-01-01
        • 2015-02-04
        • 2018-04-17
        • 1970-01-01
        • 1970-01-01
        • 2011-08-23
        相关资源
        最近更新 更多