tags:

views:

183

answers:

4
+5  Q: 

Virtual function

class a
{
 virtual void foo(void) ;
};

class b : public  a
{
public:
 virtual void foo(void)
  {
  cout<< "class b";
  }
};

int main ( ) 
{
class a *b_ptr = new b ;
b_ptr->foo();
}

please guide me why the b_ptr->foo() will not call the foo() function of the class b?

A: 

Make that

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

You can't override a private function. Though I'm not sure how you managed to call b_ptr->foo() anyways since a::foo is private.

John Kugelman
This is not true. You certainly can override a private function - it's actually quite good practice.
Jesse Beder
I don't understand what you mean. Explain?
John Kugelman
It's legal to override a private function; it's just private, so you can't call it (through the base class) by a non-friend. It's common practice to use mostly private virtual functions that are called only by the base class's member functions. I forget what this pattern is called, but it's one way of getting modifiable sub-behavior when there's an overall algorithm that stays fixed. For example, if you were writing a generic pager, its print function might be: WritePageNumber, WriteHeader, WriteNLines, WriteFooter, each of which could be modified, but the overall behavior is consistent.
Jesse Beder
Here's a nice article explaining why: http://www.gotw.ca/publications/mill18.htm
Jesse Beder
It's called the "Template Method" design pattern.
Brian Neal
I had no idea. Thanks guys. I had no idea it's legal to override private methods. I'll leave this up cause of the comments. :-)
John Kugelman
+14  A: 

As you've written the code, it won't compile due to access control violations. Since b_ptr is actually of type a * and a::foo is private, the compiler won't allow that.

But make a::foo public and that will correctly call b::foo.

There is also the problem that you have not defined a::foo so your program won't link. You need to either define it or make it pure virtual (i.e virtual void foo(void) = 0;).

R Samuel Klatchko
+1 You might want to say access *specification* violations to distinguish this from what happens when you have a rogue pointer :P
Billy ONeal
@BillyONeal - I liked the gist of your recommendation although I decided to go with access *control* violation as that is closer to how the standard describes this issue.
R Samuel Klatchko
+2  A: 

Because a:foo() is not public.

shf301
A: 
Michael Aaron Safyan
`main` implicitly returns 0.
GMan
@GMan: How do you tell the difference between someone who wanted to `return 0` and so didn't write anything, and someone who forgot to think about returning a value at all?
Bill
@Bill: I dunno. They forgot a return in a function requiring a return?
GMan
@Gman: As you pointed out, `main` doesn't require a `return`. How do you tell the difference there?
Bill
@Bill: You don't. What's your point? We don't need to waste time walking down a primrose path like there's some deeper meaning here. Item 3 is misinformed, it doesn't mention anything about what I said. The correct point would be "You probably forgot to return 0, though you got lucky here because `main` implicitly returns 0". Mention the concern along with why it still worked.
GMan
@Gman: Ah, I see. I thought you meant that because `main` implicitly returns 0 that item 3 didn't need to be there at all. Never mind!
Bill