Thread overview
Distinct "static" parent property contents for children
Nov 08, 2017
Timoses
Nov 08, 2017
Timoses
Nov 08, 2017
Adam D. Ruppe
Nov 09, 2017
Timoses
Nov 09, 2017
Timoses
Nov 10, 2017
Timoses
November 08, 2017
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?
November 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)


November 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.
November 08, 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
November 09, 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:
>> 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.
November 09, 2017
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.
November 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 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
November 10, 2017
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.