4

Why does this code not compile? (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;
}

Build log:

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

Why does the compiler fail to see 'int value()' from Base when using Derived*?

Changing

Derived * instance = new Derived();

to

Base * instance = new Derived();

works (but I need the derived pointer in my case).

Also renaming the base getter/setter functions to say getValue() and setValue(int) works. I can use various workarounds for my code, but I was just curious as to why this code fails to compile.

Mat
  • 202,337
  • 40
  • 393
  • 406
Daniel Hanrahan
  • 4,801
  • 7
  • 31
  • 44
  • 2
    possible duplicate of [Why does an overridden function in the derived class hide other overloads of the base class?](http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the) – Mat May 31 '12 at 16:41

3 Answers3

11

This is how the language works: When a child class overrides a member of a name it hides all the non-overridden names in the parent. This is to prevent accidentally combining base and parent methods that should be overridden as sets.

You can put using Base::value; in your child class to bring in the parent methods.

Mark B
  • 95,107
  • 10
  • 109
  • 188
3

The function value in the derived class hides the function in the base class.

You need to bring the base class functions into the scope of the derived class as:

class Derived : public Base {
public:

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

    void value (int Val) {
            // do some stuff here...
    }
};
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

Besides the other answers given, in addition to adding using Base::value in the child class, you can also do the following,

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

Where you specifically tell the compiler to use Base's value function. Although technically this works, it forces a bit of indirection and if you see yourself doing this often you may want to rethink how you are structuring your code.

juicedatom
  • 211
  • 2
  • 7