digitalmars.D.learn - Distinct "static" parent property contents for children
- Timoses (47/47) Nov 08 2017 Hey,
- Timoses (3/16) Nov 08 2017 To elaborate: Every instance of A or B would allocate x PER
- Adam D. Ruppe (7/8) Nov 08 2017 What are you actually trying to achieve? What are you using these
- Timoses (26/34) Nov 09 2017 Well, I have the following outline:
- Steven Schveighoffer (24/28) Nov 08 2017 [snip]
- Timoses (21/50) Nov 09 2017 I suppose this is what Adam suggested, correct?
- Steven Schveighoffer (32/57) Nov 09 2017 Yes, more or less. It's just an actual implementation vs. a description
- Timoses (5/16) Nov 09 2017 Greatly elaborated! Thank you, Steve!
Hey, wrapping my head around this atm.. How would I achieve that children statically set a property of the parent so that the property is distinct between different children? The following is *bs*, but kind of illustrates what I'd "like": class Base { int x; } class A : Base { static this() { x = 1; } } class B : Base { static this() { x = 2; } } The dilemma lies in 2 options and their drawbacks: Option 1: class Base { } class A : Base { static int x = 1; } class B : Base { static int x = 2; } Con: In the above Base does not have access to "x".... Option 2: class Base { int x;} class A : Base { this() { x = 1; } } class B : Base { this() { x = 2; } } Con: Well, the downside is that every instance of A and B allocates space for x although only one allocation would be required.. I have found the following propsition: https://stackoverflow.com/questions/11516066/d-inheriting-static-variables-differentiating-by-class However, that would remove the hierarchy.. Are there better options/ways of achieving this?
Nov 08 2017
On Wednesday, 8 November 2017 at 17:38:27 UTC, Timoses wrote:Option 2: class Base { int x;} class A : Base { this() { x = 1; } } class B : Base { this() { x = 2; } } Con: Well, the downside is that every instance of A and B allocates space for x although only one allocation would be required..To elaborate: Every instance of A or B would allocate x PER instance of A or B (where one allocation for A or B would suffice)
Nov 08 2017
On Wednesday, 8 November 2017 at 17:38:27 UTC, Timoses wrote:Are there better options/ways of achieving this?What are you actually trying to achieve? What are you using these variables for? My first thought is you should abandon the variable approach and just use an abstract function that returns the value for each child via overriding. It won't be static, but it also won't take any per-instance memory.
Nov 08 2017
On Wednesday, 8 November 2017 at 17:46:42 UTC, Adam D. Ruppe wrote:On Wednesday, 8 November 2017 at 17:38:27 UTC, Timoses wrote:Well, I have the following outline: class File { Section[] sections; } abstract class Section { enum Part { Header, Content, Footer}; SectionEntry[Part] entries; } class SectionEntry { bool isComment; string[] lines; } And then I'd like to have somthing like predefined sections, e.g.: class SectionTypeA : Section { .... // provide "static" information that is // always the same for this type of seciton // however, the Content part may vary } Are there more elegant ways of achieving this?Are there better options/ways of achieving this?What are you actually trying to achieve? What are you using these variables for?My first thought is you should abandon the variable approach and just use an abstract function that returns the value for each child via overriding. It won't be static, but it also won't take any per-instance memory.Sounds like a good approach. I'll try this out for sure.
Nov 09 2017
On 11/8/17 12:38 PM, Timoses wrote:Hey, wrapping my head around this atm..[snip] so what you want is a static variable per subclass, but that the base class can access. What I would recommend is this: abstract class Base { int x(); } class A : Base { private static int _x = 1; int x() { return _x; } } class B : Base { private static int _x = 2; int x() { return _x; } } Note that this doesn't do *everything* a static variable can, since x() requires an instance (i.e. you can't do A.x). But the actual variable itself is static since the backing is static. This is the only way to provide access of x to the Base that I can think of. -Steve
Nov 08 2017
On Wednesday, 8 November 2017 at 18:33:15 UTC, Steven Schveighoffer wrote:On 11/8/17 12:38 PM, Timoses wrote:I suppose this is what Adam suggested, correct? This is a more general question: Why is it not possible to implement/override static methods? interface I // or abstract class I { static int fun(); } class A : I { static int fun() { return 3; } } void main() { I i = new A(); i.fun(); // <--- linker error } or replacing interface with an abstract base class. Static overriding would be quite interesting in terms of compile-time handling of objects.Hey, wrapping my head around this atm..[snip] so what you want is a static variable per subclass, but that the base class can access. What I would recommend is this: abstract class Base { int x(); } class A : Base { private static int _x = 1; int x() { return _x; } } class B : Base { private static int _x = 2; int x() { return _x; } } Note that this doesn't do *everything* a static variable can, since x() requires an instance (i.e. you can't do A.x). But the actual variable itself is static since the backing is static. This is the only way to provide access of x to the Base that I can think of. -Steve
Nov 09 2017
On 11/9/17 7:34 AM, Timoses wrote:I suppose this is what Adam suggested, correct?Yes, more or less. It's just an actual implementation vs. a description in case it wasn't clear.This is a more general question: Why is it not possible to implement/override static methods?Static methods aren't virtual. There isn't a notion of a vtable for static methods on a class -- they are simply normal functions in a different namespace. I know other languages allow this, D does not.interface I // or abstract class I { static int fun();This is actually a non-virtual method, it needs an implementation.} class A : I { static int fun() { return 3; }Note, that this isn't necessary to implement I. In other words: class A : I {} also works.} void main() { I i = new A(); i.fun(); // <--- linker errorThis is calling I.fun, which has no implementation.} or replacing interface with an abstract base class. Static overriding would be quite interesting in terms of compile-time handling of objects.In a way, static overriding *does* work at compile time: class A { static int i() { return 1; } } class B : A { static int i() { return 2; } } assert(A.i == 1); assert(B.i == 2); But what you are asking is to have an instance of B, even when statically typed as A, call the derived version of the static method. In essence, this is super-similar to a virtual method, but instead of taking an instance, it wouldn't need to. But the key here is you *need* an instance for it to make any sense. It's not much different from what Adam and I suggested. The only thing you are missing is the ability to call the virtual member without an instance. But if you name your functions properly, and follow a convention, it will work for you. -Steve
Nov 09 2017
On Thursday, 9 November 2017 at 14:34:10 UTC, Steven Schveighoffer wrote:On 11/9/17 7:34 AM, Timoses wrote:Greatly elaborated! Thank you, Steve! I hope the vtable stuff is gonna be mentioned in the lectures I'm currently watching : P.I suppose this is what Adam suggested, correct?Yes, more or less. It's just an actual implementation vs. a description in case it wasn't clear. [...] It's not much different from what Adam and I suggested. The only thing you are missing is the ability to call the virtual member without an instance. But if you name your functions properly, and follow a convention, it will work for you. -Steve
Nov 09 2017