-1

Okay, so I know there are a lot of polymorphism threads flying around but I have yet to encounter this situation.

class Base {
public:
    virtual void method1() {
        cout << "BaseMethod1" << endl;
    }

    void method2() {
        cout << "BaseMethod2" << endl;
    }
};

class Derive: public Base {
public:
    void method1() {
        cout << "DeriveMethod1" << endl;
        method2();
    }

    void method2() {
        cout << "DeriveMethod2" << endl;
    }
};

int main() {
    Base* p = new Derive();
    p->method1();
}

What's tripping me up is method1 in the derived class calls a method2. So which method2 would it be since the method2 in the Base class wasn't declared as virtual?

Thanks ahead of time!

7
  • 2
    method2() parenthesis are missing if I am not wrong Commented Mar 1, 2013 at 4:55
  • 1
    @Pubby trying things won't necessarily lead to enlightenment in C++. In fact it can lead to a dangerous false sense of security in the case of undefined behavior that happens to work. Commented Mar 1, 2013 at 4:56
  • 6
    The key phrase you want to look up to answer this question is "name hiding". Commented Mar 1, 2013 at 4:56
  • -1. Do a basic research first since this is a very basic question, ask the compiler, then perhaps ask a more specific question. Commented Mar 1, 2013 at 4:59
  • 1
    @Antimony well if you prefer to read the standard then have it your way. All I care is that people do a little research before asking questions. Commented Mar 1, 2013 at 4:59

3 Answers 3

4

The code in question will not compile because Base::method1() is declared private. It needs to be public to be able to be called from main.


Derived::method1() is implicitly virtual even if not marked as virtual. So the this in Derived::method1() points to a Dervied object and in this scope compiler can only see Derived::method2(). Hence Derived::method2() will be called. The method in derived class hides the same named method in Base class.


Good Read:

What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?

Sign up to request clarification or add additional context in comments.

Comments

2

The main reason you do not see this pattern very often is that it is in fact an anti-pattern.

The Derived method will be invoked because you are calling it with a Derived object reference (this). If you were calling it with a Base class reference you will get the Base method.

If you redeclare a non-virtual method you are hiding the base method and breaking polymorphism.

2 Comments

+1 for several good points (especially significance of this), but regarding "redeclare a non-virtual method [is] breaking polymorphism" - that's a bit melodramatic: the object may continue to work polymorphically through a Base class reference/pointer perfectly well - as per Liskov Substitution Principle - or it may even be necessary not to have some functions virtual to avoid breaking the principle (e.g. a Derived class serialisation method that wasn't reparsable as per Base method documentation). Not broken, but fragile (e.g. harder to switch to compile-time polymorphism).
Good point. There are almost always exceptions to the rule. I tend to stick with this particular rule pretty heavily as it reduces the likelihood of error in large code bases. This is a contradiction to what one would expect. I guess you could say it inflates polymorphism because now you are making an object that takes many forms based on how you refer to it :P.
1

It will use Derive::method2() as name look-up (in body of Derive::method1()) starts from the class itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.