www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - class variable initialization

reply NonNull <non-null use.startmail.com> writes:
I want a way to default initialize a class variable to a default 
object (e.g. by wrapping it in a struct, because initialization 
to null cannot be changed directly). Such a default object is of 
course not available at compile time which seems to make this 
impossible. Can this be done in some way?
Apr 15 2023
next sibling parent reply Vijay Nayar <madric gmail.com> writes:
On Saturday, 15 April 2023 at 14:05:17 UTC, NonNull wrote:
 I want a way to default initialize a class variable to a 
 default object (e.g. by wrapping it in a struct, because 
 initialization to null cannot be changed directly). Such a 
 default object is of course not available at compile time which 
 seems to make this impossible. Can this be done in some way?
Assuming you want a default object that is unique per class instance rather than shared among all instances of the same class, then I think the constructor might be where you want to initialize such a member. E.g. ``` class Var { int val; this(int val) { this.val = val; } } class MyClass { Var var; this() { var = new Var(3); } } ``` I believe if you do initialization at the class declaration level, then every instance of the class shares the same instance, e.g.: ``` class Var {} class MyClass { Var var = new Var(); } void main() { MyClass c1 = new MyClass(); MyClass c2 = new MyClass(); assert(c1.var is c2.var); } ```
Apr 15 2023
parent NonNull <non-null use.startmail.com> writes:
On Saturday, 15 April 2023 at 14:17:19 UTC, Vijay Nayar wrote:
 I believe if you do initialization at the class declaration 
 level, then every instance of the class shares the same 
 instance, e.g.:

 ```
 class Var {}

 class MyClass {
   Var var = new Var();
 }

 void main() {
   MyClass c1 = new MyClass();
   MyClass c2 = new MyClass();
   assert(c1.var is c2.var);
 }
 ```
I should have made it clear that want a single shared default object. Your code above solves that problem. So does ``` Var defaultObj; static this() { defaultObj = new Var(); } ``` By wrapping the new variable and the constructor call to initialize it in MyClass, you eliminate the need to call the constructor, which is what I want, but now you add the need to call another constructor. So for my purposes this is just moving the problem of null to another place.
Apr 15 2023
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/15/23 7:05 AM, NonNull wrote:
 I want a way to default initialize a class variable to a default object 
 (e.g. by wrapping it in a struct, because initialization to null cannot 
 be changed directly). Such a default object is of course not available 
 at compile time which seems to make this impossible. Can this be done in 
 some way?
You can construct objects at compile time. If I understand your question properly: ```d struct Wrapper { Object x = new Object(); alias x this; } void foo(Object o) { assert(o !is null); } void main() { Wrapper w; foo(w); } ``` -Steve
Apr 15 2023
parent reply NonNull <non-null use.startmail.com> writes:
On Saturday, 15 April 2023 at 15:47:40 UTC, Steven Schveighoffer 
wrote:
 You can construct objects at compile time.

 If I understand your question properly:

 ```d
 struct Wrapper
 {
    Object x = new Object();
    alias x this;
 }

 void foo(Object o)
 {
    assert(o !is null);
 }

 void main()
 {
    Wrapper w;
    foo(w);
 }
 ```

 -Steve
Amazing, was this always so?
Apr 15 2023
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/15/23 09:06, NonNull wrote:

 struct Wrapper
 {
    Object x = new Object();
    alias x this;
 }
 Amazing, was this always so?
At least for a long time. However, every Wrapper object will have a pointer to that single shared object. If you think that cost is unnecessary, you can have a static variable: struct Wrapper { static Object x; alias x this; } static this() { Wrapper.x = new Object(); } However, because such data are thread-local by-default, not the entire class, but each thread will have a copy that variable. When you want a single class variable for all threads, then it must be defined as shared: struct Wrapper { shared static Object x; alias x this; } shared static this() { Wrapper.x = new Object(); } void foo(shared Object o) { assert(o !is null); } Note how foo's interface had to be changed as well. And of course you may have to provide thread synchronization when that variable needs to be mutated at run time. Ali
Apr 15 2023