1
struct Base{
    virtual void foo(){
        std::cout << "In Base\n";
    }
};
struct Derived : public virtual Base{
    virtual void foo() const{
        std::cout << "In Derived\n";
    }
};
Base* d = new Derived();

int main(int argc,char** args){
    d->foo();
    system("Pause");
}

When I run this code "In Base" is printed. Why does having the const specifier change the inheritance?

DarthRubik
  • 3,927
  • 1
  • 18
  • 54
  • Because it's a totally different overload? – Edward Strange Apr 15 '16 at 21:13
  • @LogicStuff It is not a duplicate of that question, because in that question the base had the const function, in mine I have the derived as a const....This I would think would mean that the const modifier would not effect the orignal function (because it is only adding constness not taking away....) – DarthRubik Apr 15 '16 at 21:14
  • @DarthRubik it doesn't matter which version is const and which isn't, the logic is the same either way. You're defining two different functions with two different signatures (but the same name). – Mark Ransom Apr 15 '16 at 21:17
  • @MarkRansom That is weird....you would think that It would complain if you where const in the base but not the derived, but if you were const in the derived but not in the base you would **think** that it would not matter.... – DarthRubik Apr 15 '16 at 21:18
  • @DarthRubik it might not be intuitive, but when you understand function signatures it makes perfect sense. It doesn't complain because you've defined two completely different, unrelated functions! – Mark Ransom Apr 15 '16 at 21:34
  • @MarkRansom Interesting... – DarthRubik Apr 15 '16 at 21:35

2 Answers2

3

The const changes the signature of function. So it's an overload an not an override.

If you want to be sure not to make these kind of mistakes, you may use override. This will detect these kind of mismatches and generate errors.

This would then fail to compile:

struct Base{
    virtual void foo(){
        std::cout << "In Base\n";
    }
};
struct Derived : public virtual Base{
    void foo() const override {    // <====  ouch: error because it's a different signature 
        std::cout << "In Derived\n";
    }
};

And this would compile succesfully:

struct Base{
    virtual void foo() const{
        std::cout << "In Base\n";
    }
};
struct Derived : public virtual Base{
    void foo() const override {    // <====  signatures do match
        std::cout << "In Derived\n";
    }
};
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Actually, in this case it doesn't overload either...it hides. You cannot call foo() on a non-const Derived unless you first cast it to Base. – Edward Strange Apr 15 '16 at 21:15
2
  1. virtual void foo() and virtual void foo() const are two completely different functions. The const member function in the derived class does not override the non-const member function in the base class.

  2. Given the choice of a const member function and a non-const member function, the non-const member function is given higher priority.

R Sahu
  • 204,454
  • 14
  • 159
  • 270