www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - virtual functions changing from protected to private - question

reply MatthiasM <dm matthiasm.com> writes:
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
Sep 05 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Sep 05 2006
next sibling parent MatthiasM <dm matthiasm.com> writes:
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... .
Sep 05 2006
prev sibling parent Steve Horne <stephenwantshornenospam100 aol.com> writes:
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.
Sep 06 2006