www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - 2 class issues

reply spir <denis.spir gmail.com> writes:
Hello,

First, I am not very experimented with the combination of static lang (alloc & 
typing) and OO (class-based). I'm implementing a library for lexical analysis 
(lexing), with 2 minor issues:

-1- How to enforce that subclasses implement given methods without using 
"abstract", which seems to make the whole class abstract? (no info found in
doc, 
actually, the page on classes [1] does not seem to even mention abstract
classes)

-2- How to have "constant" (predefined) class instances at the module-level?
The 
compiler requires a "static this ()". What does this actually mean (for a 
constructor)? What are the consequences, for either my code or client code?
(The 
doc on the topic [2] is rather obscure for me, and I could not find better 
elsewhere.)

I'm also bluffed by "Static constructors have empty parameter lists." Does this 
mean I should manually fill the fields? (not a big deal, but why???) This may
give:
     // Predefined pseudo-pattern "End-of-Text":
     auto EoT = new Pattern() ;       // ???
     EoT.name = "EoT" ;

     // Unique lexeme "end-of-text":
     auto eot = new Lexeme() ;       // ???
     eot.patname = "EoT" ;
     eot.slice = null ;
     eot.index = uint.max ;
Then, why have a constructor at all? This would also prevent me from making 
classes immutable, while conceptually all are immutable... (no reason for a 
pattern or a lexeme to change)

Thank you,
diniz

[1] https://dlang.org/spec/class.html
[2] https://dlang.org/spec/class.html#static-constructor
Mar 07
next sibling parent Johannes Loher <johannesloher fg4f.de> writes:
Am 07.03.19 um 11:38 schrieb spir:
 Hello,
 
 First, I am not very experimented with the combination of static lang
 (alloc & typing) and OO (class-based). I'm implementing a library for
 lexical analysis (lexing), with 2 minor issues:
 
 -1- How to enforce that subclasses implement given methods without using
 "abstract", which seems to make the whole class abstract? (no info found
 in doc, actually, the page on classes [1] does not seem to even mention
 abstract classes)
 
 -2- How to have "constant" (predefined) class instances at the
 module-level? The compiler requires a "static this ()". What does this
 actually mean (for a constructor)? What are the consequences, for either
 my code or client code? (The doc on the topic [2] is rather obscure for
 me, and I could not find better elsewhere.)
 
 I'm also bluffed by "Static constructors have empty parameter lists."
 Does this mean I should manually fill the fields? (not a big deal, but
 why???) This may give:
     // Predefined pseudo-pattern "End-of-Text":
     auto EoT = new Pattern() ;       // ???
     EoT.name = "EoT" ;
 
     // Unique lexeme "end-of-text":
     auto eot = new Lexeme() ;       // ???
     eot.patname = "EoT" ;
     eot.slice = null ;
     eot.index = uint.max ;
 Then, why have a constructor at all? This would also prevent me from
 making classes immutable, while conceptually all are immutable... (no
 reason for a pattern or a lexeme to change)
 
 Thank you,
 diniz
 
 [1] https://dlang.org/spec/class.html
 [2] https://dlang.org/spec/class.html#static-constructor
Regarding your first point: I don't think it is currently possible to force derived classes to override functions from the base class while also implementing these functions in the base class. What would the usecase of this be anyways? Regarding your second point: What excatly do you mean by '"constant" (predefined) class'? Do you mean that you want to provide an instant from that class? You can achieve this like the following: ``` class Test { } Test testInstance; static this() { testInstance = new Test(); } ``` If you want the testInstance to be shared across threads: ``` class Test { } shared Test testInstance; shared static this() { testInstance = new Test(); } ``` You seem to be misunderstanding how static class constructors work: They are not invoked when you try to instanciate the class, but when the module in which the class is located is loaded. This also explains why they need to have empty parameter lists: You cannot pass arguments when loading a module static constructors are usually used to initialize static class variables. Consider the following example: ``` import core.thread: Thread; class Test { private static ulong i; static this() { i = Thread.getThis.id; } } ``` You cannot initialize `i` directly in its declaration because `Thread.getThis.id` is only available at runtime (i.e. `private static ulong i = Thread.getThis.id;` does not compile). To get around this, you can use static constructors.
Mar 07
prev sibling parent ag0aep6g <anonymous example.com> writes:
On 07.03.19 11:38, spir wrote:
 -1- How to enforce that subclasses implement given methods without using 
 "abstract", which seems to make the whole class abstract?
Not, as far as I can tell. You can't force derived classes to override an existing implementation. And you can't omit the implementation without making the class abstract.
 -2- How to have "constant" (predefined) class instances at the 
 module-level?
Just like so? const o = new Object; /* works for me */
 The compiler requires a "static this ()".
For what code does it say that?
 What does this 
 actually mean (for a constructor)? What are the consequences, for either 
 my code or client code? (The doc on the topic [2] is rather obscure for 
 me, and I could not find better elsewhere.)
 
 I'm also bluffed by "Static constructors have empty parameter lists." 
 Does this mean I should manually fill the fields? (not a big deal, but 
 why???) This may give:
      // Predefined pseudo-pattern "End-of-Text":
      auto EoT = new Pattern() ;       // ???
      EoT.name = "EoT" ;
 
      // Unique lexeme "end-of-text":
      auto eot = new Lexeme() ;       // ???
      eot.patname = "EoT" ;
      eot.slice = null ;
      eot.index = uint.max ;
 Then, why have a constructor at all? This would also prevent me from 
 making classes immutable, while conceptually all are immutable... (no 
 reason for a pattern or a lexeme to change)
You're misunderstanding the nature of static constructors. Static constructors are a special kind of function that runs once at the beginning of the program/thread, automatically. They're not constructors for static objects. You can't call static constructors from your code. `new Foo` calls a (normal) constructor; doesn't matter if you're creating a dynamic instance or a static one.
Mar 07