digitalmars.D.learn - access subclass functions
- Saaa (11/11) Nov 20 2008 Is this not possible, or am I doing anything wrong?
- Steven Schveighoffer (13/24) Nov 20 2008 I think you have a typo in your example (and your example doesn't reflec...
- Saaa (12/25) Nov 20 2008 How do you mean? Like not at all?
- Steven Schveighoffer (4/8) Nov 20 2008 I mean, you have some cast error, but there is no casting in your code
- Saaa (4/13) Nov 20 2008 My bad, I meant:
- BCS (3/6) Nov 20 2008 I'm not shure that will work. IIRC DMD reads that as
- Kagamin (2/5) Nov 20 2008 why not using struct?
- sclytrack (19/30) Nov 20 2008 from the list (private, protected, public) pick public.
- Saaa (4/22) Nov 20 2008 I can? :D
- Christopher Wright (22/42) Nov 20 2008 Informally, "virtual" means "can be overridden". It only applies to
- Jarrett Billingsley (3/5) Nov 20 2008 OhhhhhhhhhhhHHHHHHHHHHHHHHHHHHHHHH
- Saaa (13/34) Nov 20 2008 virtual functions are slowers because you have the extra step of
- Christopher Wright (40/51) Nov 20 2008 There are two issues, both relating to caching. First, your vtbl might
- Saaa (2/51) Nov 20 2008
Is this not possible, or am I doing anything wrong? Fruit[2] fruits; // Fruit has no peel function fruit[0]= new Apple(); fruit[1]= new Banana(); //Banana has a protected peel() function returning a bool bool b; b=fruit[1].peal(); Error: no property 'peel' for type 'project.fruitclass.Fruit' Error: function expected before (), not 1 of type int Error: cannot implicitly convert expression (cast(Banana)1()) of type 'project.banana.Banana' to bool
Nov 20 2008
"Saaa" wroteIs this not possible, or am I doing anything wrong? Fruit[2] fruits; // Fruit has no peel function fruit[0]= new Apple(); fruit[1]= new Banana(); //Banana has a protected peel() function returning a bool bool b; b=fruit[1].peal(); Error: no property 'peel' for type 'project.fruitclass.Fruit' Error: function expected before (), not 1 of type int Error: cannot implicitly convert expression (cast(Banana)1()) of type 'project.banana.Banana' to boolI think you have a typo in your example (and your example doesn't reflect the error messages), but that isn't the problem. In a strongly typed language, you cannot access subclass functions that aren't defined in the base class unless you are sure the instance is of the subclass type. to fix, you should do this: if(auto ban = cast(Banana)fruit[1]) ban.peel(); the if(auto ban = ...) ensures that fruit[1] is a Banana. If you are sure it will always be a banana (i.e. the cast doesn't return null), you can do: (cast(Banana)fruit[1]).peel(); -Steve
Nov 20 2008
I think you have a typo in your example:)(and your example doesn't reflect the error messages),How do you mean? Like not at all? As you noticed it isn't the actual code, but I thought it would reflect it though.but that isn't the problem. In a strongly typed language, you cannot access subclass functions that aren't defined in the base class unless you are sure the instance is of the subclass type. to fix, you should do this: if(auto ban = cast(Banana)fruit[1]) ban.peel(); the if(auto ban = ...) ensures that fruit[1] is a Banana. If you are sure it will always be a banana (i.e. the cast doesn't return null), you can do: (cast(Banana)fruit[1]).peel();Yay, thanks! Now that you mention it, I think I've had this problem before :/ even though it is really logical, thx again. In stead of numbers I use an enum, which makes it really difficult to get this wrong: fruits[BANANA].peel(); :D Now that I got this out of the way I see peel() should be public.
Nov 20 2008
"Saaa" wroteI mean, you have some cast error, but there is no casting in your code sample. -Steve(and your example doesn't reflect the error messages),How do you mean? Like not at all? As you noticed it isn't the actual code, but I thought it would reflect it though.
Nov 20 2008
My bad, I meant: b=cast(Banana)fruits[1].peel(); "Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:gg3p0v$2494$1 digitalmars.com..."Saaa" wroteI mean, you have some cast error, but there is no casting in your code sample. -Steve(and your example doesn't reflect the error messages),How do you mean? Like not at all? As you noticed it isn't the actual code, but I thought it would reflect it though.
Nov 20 2008
Reply to Saaa,b=cast(Banana)fruits[1].peel();I'm not shure that will work. IIRC DMD reads that as b=cast(Banana)( fruits[1].peel() );
Nov 20 2008
Saaa Wrote:In stead of numbers I use an enum, which makes it really difficult to get this wrong: fruits[BANANA].peel();why not using struct?
Nov 20 2008
"Kagamin" <spam here.lot> wrote in message news:gg3t81$2flu$1 digitalmars.com...Saaa Wrote:How do you mean? What should be a struct?In stead of numbers I use an enum, which makes it really difficult to get this wrong: fruits[BANANA].peel();why not using struct?
Nov 20 2008
Saaa Wrote:typed array.How do you mean? What should be a struct?this wrong: fruits[BANANA].peel();why not using struct?
Nov 21 2008
You mean something like this ? struct fruits { Banana banana(); Apple apple(); } I now use foreach(int i, Fruit fruit; fruits) a lot. How do I iterate over all elements when I use the above?Saaa Wrote:typed array.How do you mean? What should be a struct?this wrong: fruits[BANANA].peel();why not using struct?
Nov 21 2008
== Quote from Saaa (empty needmail.com)'s articleIs this not possible, or am I doing anything wrong? Fruit[2] fruits; // Fruit has no peel function fruit[0]= new Apple(); fruit[1]= new Banana(); //Banana has a protected peel() function returning a bool bool b; b=fruit[1].peal(); Error: no property 'peel' for type 'project.fruitclass.Fruit' Error: function expected before (), not 1 of type int Error: cannot implicitly convert expression (cast(Banana)1()) of type 'project.banana.Banana' to boolfrom the list (private, protected, public) pick public. Note the difference between peel and peal. public YellowBanana: Banana { void doStuff() { bool e = peel(); //visible from derived //class when defined protected or public. } } Banana a = new Banana(); bool f = a.peel(); //visible only when public All non-static non-private non-template member functions are virtual. (Rule only valid in D) If you want to peel your fruit your fruit needs a peel member function, or else you need to cast it (dynamic_cast). You can make an abstract virtual function (pure virtual function). What kind of a programme are you making? Just curious.
Nov 20 2008
from the list (private, protected, public) pick public. Note the difference between peel and peal.:)public YellowBanana: Banana { void doStuff() { bool e = peel(); //visible from derived //class when defined protected or public. } } Banana a = new Banana(); bool f = a.peel(); //visible only when public All non-static non-private non-template member functions are virtual. (Rule only valid in D)What does this mean: to be virtual?If you want to peel your fruit your fruit needs a peel member function, or else you need to cast it (dynamic_cast). You can make an abstract virtual function (pure virtual function).I can? :DWhat kind of a programme are you making? Just curious.A game, containing loads of fruits.
Nov 20 2008
Saaa wrote:Informally, "virtual" means "can be overridden". It only applies to methods on classes. This definition is informal and ambiguous. According to __traits in d2, "virtual" means "might have a vtbl entry". A vtbl is a list of function pointers corresponding to the methods of a class. Each instance of that class has a pointer to the same list. Virtual dispatch just consists of pointing to a different vtbl with a different function in that slot. Anyway, the __traits definition maps to the following lemmas[1]: - static is not virtual - template is not virtual - private is not virtual On the other hand, final functions are virtual. If a final function does not override a virtual function, the compiler can turn it into a free function if that's more efficient. Or maybe not. If a final function overrides a virtual function, it will certainly end up in the class vtbl. Final functions are a bit questionable. If they override a virtual method in a base class, they should certainly be considered virtual, but you also sometimes need to know whether you can override a function. That is when it's not final and it is virtual. [1] It's a bit of a stretch to grant them this name, but if life gives you lemmas, make lemma-ade.from the list (private, protected, public) pick public. Note the difference between peel and peal.:)public YellowBanana: Banana { void doStuff() { bool e = peel(); //visible from derived //class when defined protected or public. } } Banana a = new Banana(); bool f = a.peel(); //visible only when public All non-static non-private non-template member functions are virtual. (Rule only valid in D)What does this mean: to be virtual?
Nov 20 2008
On Thu, Nov 20, 2008 at 7:35 PM, Christopher Wright <dhasenan gmail.com> wrote:[1] It's a bit of a stretch to grant them this name, but if life gives you lemmas, make lemma-ade.OhhhhhhhhhhhHHHHHHHHHHHHHHHHHHHHHH I think my head just exploded.
Nov 20 2008
Informally, "virtual" means "can be overridden". It only applies to methods on classes. This definition is informal and ambiguous.virtual functions are slowers because you have the extra step of vtable, right? How much of a difference can I expect? Because it doesn't look like a lot of work: just one single table lookup.According to __traits in d2, "virtual" means "might have a vtbl entry". A vtbl is a list of function pointers corresponding to the methods of a class. Each instance of that class has a pointer to the same list.OkVirtual dispatch just consists of pointing to a different vtbl with a different function in that slot.Virtual dispatch?Anyway, the __traits definition maps to the following lemmas[1]: - static is not virtual- there is only one function shared with between all the object.- template is not virtual- I've never used these- private is not virtualOkOn the other hand, final functions are virtual. If a final function does not override a virtual function, the compiler can turn it into a free function if that's more efficient. Or maybe not. If a final function overrides a virtual function, it will certainly end up in the class vtbl.I have never used final either :)Final functions are a bit questionable. If they override a virtual method in a base class, they should certainly be considered virtual, but you also sometimes need to know whether you can override a function. That is when it's not final and it is virtual.When I need to know whether I can override it, it becomes virtual? How does the compiler know that I want that?[1] It's a bit of a stretch to grant them this name, but if life gives you lemmas, make lemma-ade.:)
Nov 20 2008
Saaa wrote:There are two issues, both relating to caching. First, your vtbl might not be in cache, which means an expensive memory lookup. Second, the cpu has a cache of instructions you're about to execute; with a non-virtual function, that's a fixed target, so the cpu can do better prefetching. In practice, your typeinfo is probably reasonably high in your cache, so it won't take very long. A smart compiler should probably put all the vtbls in the same region of memory, ideally arranged according to inheritance. (Maybe not, I'm not an expert.) Actually arranging this is probably quite impossible. At any rate, if your performance is bad, you'd be better off profiling. If profiling doesn't show anything interesting and you still need a minor performance boost, you can try marking everything as final. If your code consists entirely of function calls, you might get a 20-50% speed increase. If it's more typical code, maybe a 2% speed increase. (Judging by random microbenchmarks I've seen on the intarwebs.)Informally, "virtual" means "can be overridden". It only applies to methods on classes. This definition is informal and ambiguous.virtual functions are slowers because you have the extra step of vtable, right? How much of a difference can I expect? Because it doesn't look like a lot of work: just one single table lookup.You make a method call. The compiler dispatches that to a particular concrete, free-floating function that happens to take a hidden parameter named 'this'. With virtual dispatch, you might call a different function depending on the type of 'this'.Virtual dispatch just consists of pointing to a different vtbl with a different function in that slot.Virtual dispatch?When I need to know whether I can override it, it becomes virtual? How does the compiler know that I want that?If it's final, you can't override it. If you override something, your override can be final: class Base { /* virtual */ void foo () { writefln("Base.foo!"); } } class Final : Base { // I'm virtual, but you can't override me. final override void foo () { writefln("Final.foo!"); } } class Fail : Final { // Told you you can't override me. override void foo () { writefln("I don't even compile :("); } } The rest of what I was saying mainly applies to people using reflection to determine whether a function can be overridden.
Nov 20 2008
Thanks !! I miss university :'(There are two issues, both relating to caching. First, your vtbl might not be in cache, which means an expensive memory lookup. Second, the cpu has a cache of instructions you're about to execute; with a non-virtual function, that's a fixed target, so the cpu can do better prefetching. In practice, your typeinfo is probably reasonably high in your cache, so it won't take very long. A smart compiler should probably put all the vtbls in the same region of memory, ideally arranged according to inheritance. (Maybe not, I'm not an expert.) Actually arranging this is probably quite impossible. At any rate, if your performance is bad, you'd be better off profiling. If profiling doesn't show anything interesting and you still need a minor performance boost, you can try marking everything as final. If your code consists entirely of function calls, you might get a 20-50% speed increase. If it's more typical code, maybe a 2% speed increase. (Judging by random microbenchmarks I've seen on the intarwebs.)Informally, "virtual" means "can be overridden". It only applies to methods on classes. This definition is informal and ambiguous.virtual functions are slowers because you have the extra step of vtable, right? How much of a difference can I expect? Because it doesn't look like a lot of work: just one single table lookup.You make a method call. The compiler dispatches that to a particular concrete, free-floating function that happens to take a hidden parameter named 'this'. With virtual dispatch, you might call a different function depending on the type of 'this'.Virtual dispatch just consists of pointing to a different vtbl with a different function in that slot.Virtual dispatch?When I need to know whether I can override it, it becomes virtual? How does the compiler know that I want that?If it's final, you can't override it. If you override something, your override can be final: class Base { /* virtual */ void foo () { writefln("Base.foo!"); } } class Final : Base { // I'm virtual, but you can't override me. final override void foo () { writefln("Final.foo!"); } } class Fail : Final { // Told you you can't override me. override void foo () { writefln("I don't even compile :("); } } The rest of what I was saying mainly applies to people using reflection to determine whether a function can be overridden.
Nov 20 2008