20

I was asked this crazy question. I was out of my wits.

Can a method in base class which is declared as virtual be called using the base class pointer which is pointing to a derived class object?

Is this possible?

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
Vijay
  • 65,327
  • 90
  • 227
  • 319
  • 9
    You might want to obtain one of the introductory books from [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – James McNellis Jun 16 '10 at 16:15
  • 2
    @James: I think he is asking if you can call `base::foo()` not `derived::foo()` using `p` if `p` is a `base*` and points to a `derived` – John Dibling Jun 16 '10 at 16:57
  • @John: So? James is right, nevertheless. – sbi Jun 16 '10 at 17:25
  • 4
    I would have asked the interviewer. Why would you want to do that as you are breaking the contract designed by the developer of the class hierarchy. If the original developer had wanted you to call the base class method he would have provided a non virtual method that performed the action. – Martin York Jun 16 '10 at 17:35
  • @John: Ok, interpreting the question that way, it's slightly more interesting. – James McNellis Jun 16 '10 at 17:44
  • 1
    @sbi: I could be wrong, but calling the base class' implementation of a virtual function seemed not all that basic to me. James is right, of course, I'm just saying this is level 201 stuff, rather than level 101 stuff. – John Dibling Jun 16 '10 at 19:01
  • @John: Well, maybe you're right. IIRC, my introduction was Stroustrup's TCPL, 2nd edition, and it certainly covered things like this. Koenig/Moo might not mention it, though. – sbi Jun 16 '10 at 19:38
  • 1
    Even if you supplied the question "as asked", a simple code snippet might help clarify what was being asked. – Dan Jun 17 '10 at 18:38

8 Answers8

51

If you're trying to invoke a virtual method from the base class pointer, yes.

That's polymorphism.

If you're asking, with a base class pointer to a derived class, can you invoke a base class method that is overriden by the derived class? Yes that's also possible by explicitly scoping the base class name:

basePtr->BaseClass::myMethod();

Alan
  • 45,915
  • 17
  • 113
  • 134
  • 4
    Polymorphism is where it class the derived class method because the method is virtual in the base class. Actually calling the base class method via a pointer to base even if the base class method has been overridden is bypassing polymorphism which is different. – CB Bailey Jun 16 '10 at 16:17
  • 1
    Actually it's the opposite. The question is asking to call the base class's virtual method when the object is of the derived type which overrides the method. – JaredPar Jun 16 '10 at 16:18
  • 5
    Hrm, the question as written was confusing. – Alan Jun 16 '10 at 16:20
  • Hmm, I never knew this was an option (guess I never needed it). Thanks! – Uri Jun 16 '10 at 16:51
  • The question wasn't very clear, but the answer made the question clear. – eeerahul Oct 07 '11 at 11:12
  • @Alan. Good option. It was not known to me also. thanks for info. – hims Jan 22 '14 at 08:45
17

Try:

class A            { virtual void foo(); }
class B : public A { virtual void foo(); }

A *b = new B();
b->A::foo ();
  • 4
    Actually I think it should be "A *b = new B()", instead of "B *b = new B()", to follow the question. – Luca Jun 16 '10 at 16:28
10

You mean something like this. (Where pBase is of type pointer-to-base but the pointed-to object is actually of type Derived which is derived from Base.)

pBase->Base::method();

Yes, it's possible.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
10

Yes -- you have to specify the full name though:

#include <iostream>

struct base { 
    virtual void print() { std::cout << "Base"; }
};

struct derived : base {
    virtual void print() { std::cout << "Derived"; }
};

int main() { 
    base *b = new derived;
    b->base::print();
    delete b;
    return 0;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
5

If I understand the question correctly, you have

class B 
{
public: 
    virtual void foo();
};

class D: public B
{
public:
    virtual void foo();
}

B* b = new D;

And the question is, can you call B::foo(). The answer is yes, using

b->B::foo()
KeithB
  • 16,577
  • 3
  • 41
  • 45
0
class B 
{
public: 
    virtual void foo();
};

class D: public B
{
public:
    virtual void foo();
}

B* b = new D;

Try calling

(*b).foo()

to invoke base class foo function

Pardeep
  • 929
  • 6
  • 14
  • are you sure that this will call base class foo function? did you test it? – Vijay Jun 18 '10 at 13:34
  • It was my general assumption that (*b) will eventually have proper object but on compile and run I found that this is not the case. It still calls derived function. This has created confusion for me also that what is the difference between (*b).foo() and B b1 = *b; b1.foo() – Pardeep Jun 21 '10 at 05:18
0
class B { 
    public: virtual void foo(); 
};

class D: public B { 
    public: virtual void foo() 
    { 
        B::foo();
    }; 
}

B* b = new D;

Solutions :

  1. b->foo();
  2. b->B::foo()

  3. OR do not override/define foo() in the derived class D and call b->foo()

  4. B objb = *b; objb.foo() ; // this is object slicing and not (*b).foo() as in one of the previous answers

gary
  • 4,227
  • 3
  • 31
  • 58
user179156
  • 841
  • 9
  • 31
-1

No. Not in a clean way. But yes. You have to do some pointer manipulation, obtain a pointer to the vtable and make a call. but that is not exactly a pointer to base class, but some smart pointer manipulation. Another approach is using scope resolution operator on base class.

Sudesh Sawant
  • 147
  • 1
  • 4
  • C++ does support directly what the question asks. `base->base::function()` would do the trick. No need to vtable hackery here. – John Dibling Jun 16 '10 at 16:59
  • 2
    Re-read your post. "scope resolution operator" is not "another approach." It is the only approach you should be considering. – John Dibling Jun 16 '10 at 17:00