www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Distinct "static" parent property contents for children

reply Timoses <timosesu gmail.com> writes:
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
next sibling parent Timoses <timosesu gmail.com> writes:
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
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent Timoses <timosesu gmail.com> writes:
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:
 Are there better options/ways of achieving this?
What are you actually trying to achieve? What are you using these variables for?
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?
 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
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
parent reply Timoses <timosesu gmail.com> writes:
On Wednesday, 8 November 2017 at 18:33:15 UTC, Steven 
Schveighoffer wrote:
 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
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.
Nov 09
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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 error
This 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
parent Timoses <timosesu gmail.com> writes:
On Thursday, 9 November 2017 at 14:34:10 UTC, Steven 
Schveighoffer wrote:
 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. [...] 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
Greatly elaborated! Thank you, Steve! I hope the vtable stuff is gonna be mentioned in the lectures I'm currently watching : P.
Nov 09