Thread overview
virtual functions changing from protected to private - question
Sep 05, 2006
MatthiasM
Sep 05, 2006
MatthiasM
Sep 06, 2006
Steve Horne
September 05, 2006
So, umm, after debugging my app for quite a while (OSX gdc), I saw that B.draw is not called. Is that intentional?

class Window {
protected:
  void draw() {
    writefln("Window");
  }
}

class MenuWindow : Window {
private:
  void draw() {
    writefln("MenuWindow");
  }
}

Window w = new MenuWindow();
w.draw();


prints "Window". I would have expected "MenuWindow", thinking that all functions are automatically virtual. I understand that private unctions are not virtual on a base class, since they can't be overridden anyways. But is that true for a derived class too?

Matthias
September 05, 2006
"MatthiasM" <dm@matthiasm.com> wrote in message news:edkk0f$2nf4$1@digitaldaemon.com...
>
> So, umm, after debugging my app for quite a while (OSX gdc), I saw that
> B.draw is not called. Is that intentional?
> I would have expected "MenuWindow", thinking that all functions are
> automatically virtual. I understand that private unctions are not virtual
> on a base class, since they can't be overridden anyways. But is that true
> for a derived class too?

Since you've made it private, the compiler makes it nonvirtual.  Since it's nonvirtual, it doesn't live in the virtual table at all.  So it doesn't override the Window.draw().  Virtual methods and nonvirtual methods live in two different places, so it's not really possible to override a virtual method with a nonvirtual method.


September 05, 2006
Jarrett Billingsley wrote:
> Since you've made it private, the compiler makes it nonvirtual.  Since it's nonvirtual, it doesn't live in the virtual table at all.  So it doesn't override the Window.draw().  Virtual methods and nonvirtual methods live in two different places, so it's not really possible to override a virtual method with a nonvirtual method. 

Thanks for verifying my assumption. I am still very much in C++ world where this is perfectly fine... .
September 06, 2006
On Tue, 5 Sep 2006 16:19:15 -0400, "Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote:

>Since you've made it private, the compiler makes it nonvirtual.  Since it's nonvirtual, it doesn't live in the virtual table at all.  So it doesn't override the Window.draw().  Virtual methods and nonvirtual methods live in two different places, so it's not really possible to override a virtual method with a nonvirtual method.

Interesting.

I don't see the point of reducing the visibility of base class members in the derived class, myself - you can always cast back to the base class to see them anyway.

Also, I'm quite comfortable with the compiler refusing to override a base class member using a private member in the derived class. After all, the privacy would be broken, as before.

Even so, I would have hoped for a compiler error or warning. After all, there are two methods with the same signature. Whether the derived class method will be referenced by the virtual table is beside the point, really - the issue is that there is probable error that should be reported by the compiler.

MatthiusM : you can always adopt a style where you use the 'override' keyword wherever that is your intent. I believe (though I am a D newbie) that this will generate a compiler error if there is no method to override. So presumably, in your example, it would fail because even though there is a super::draw, D has decided that you can't override it.

Remove 'wants' and 'nospam' from e-mail.