Daniel
Daniel

Reputation: 1263

C++ virtual method overload/override compiler error

I'm writing a little program in C++ and I what to play with polymorphism.
So the code goes like this:

//Base.h
class Base{
    public:
        void method(const objectType1& stuff1); 
        //objectType1 is whatever type you what (int, string, ...)

    protected:      
        Base(void);
        virtual ~Base(void);

        virtual void method(void) = 0;
};

//Derived.h
/*FINAL - DO NOT INHERIT THIS CLASS OR YOU WILL die :)*/
class Derived : public Base{
    public:
        Derived(void);
        ~Derived(void);

    private:
        void method(void);
};


//Main.cpp
int main(){
    objectType1 ot1;

    //this code works
    Base *bd = new Derived;
    bd->method(ot1);

    //this dosen't
    Derived *dd = new Derived;
    dd->method(ot1); 
    // he doesn't call Base::method(const objectType1& stuff1),
    // he calls Derived::method(void)

    return 0;
}

I've solved the problem by renaming the virtual method void method(void) in something else and all is well.

My questions are:

Thanks :) .

Upvotes: 0

Views: 989

Answers (2)

The member method in the base class is public, which means that any piece of code can call it. Besides being public, it is virtual, which means that the execution will be dynamically dispatched at runtime to the final overrider.

Access to the method is checked statically in the static type of the reference/pointer through which the call is dispatched, even if it will be dynamically dispatched.

On the other hand in the second case, the call is through the derived type, and the access specifier is checked at that level, where the compiler finds the member function to be private and thus complains.

In plain english, when the object is used as a base, it behaves as a base, but when used directly it behaves as derived.

Upvotes: 3

celtschk
celtschk

Reputation: 19721

The method definition in Derived hides the definition in Base. To avoid that, add using Base::method; to Derived.

This happens because when calling functions in Derived, the compiler looks into Base only if it didn't fine the name in Derived. Note that it doesn't look for the signature but only for the name in that stage. Overload resolution based on the signature is done only afterwards. This is actually not much different to the following situation:

void function(int);
void function();

int main()
{
  void function(); // this declaration hides *both* global declarations
  function(3); // error
}

In your case Base plays the role of the global scope and Derived the role of the function scope.

Also note that this is not related to virtaul fgunctions; indeed the same would happen without virtual (except that you then couldn't call Derived's method via a pointer to Base, of course, but would call the Base version instead).

Upvotes: 1

Related Questions