digitalmars.D.learn - Class member always has the same address
- szymski (8/34) Mar 19 2016 Hello!
- ag0aep6g (3/6) Mar 19 2016 The As are different, but they all reference the same B. Initialize b in...
- Mike Parker (20/23) Mar 19 2016 This is *default* initialization, not per instance
- szymski (3/26) Mar 20 2016 Ok, I understand now, thanks. I used C# a lot before and there
- Mike Parker (8/10) Mar 20 2016 Yes, I assumed you were thinking of C# or Java classes with this.
Hello! I'm having a big problem with class members. I'm kinda new to D, so this may be my fault, but look at the following code:import std.stdio; class B { int variable; } class A { B b = new B(); } void main() { // Create 10 instances of A foreach(i; 0 .. 10) { auto a = new A(); writeln(&a.b.variable, " = ", a.b.variable); // Print a.b.variable address and its value a.b.variable++; } }When ran, it prints something totally different from what I expect:430088 = 0 430088 = 1 430088 = 2 430088 = 3 430088 = 4 430088 = 5 430088 = 6 430088 = 7 430088 = 8 430088 = 9In my opinion &a.b.variable should give different addresses for each instance of A, because it's not static. What am I doing wrong? Thanks in advance.
Mar 19 2016
On 19.03.2016 21:24, szymski wrote:In my opinion &a.b.variable should give different addresses for each instance of A, because it's not static. What am I doing wrong? Thanks in advance.The As are different, but they all reference the same B. Initialize b in a constructor instead.
Mar 19 2016
On Saturday, 19 March 2016 at 20:24:15 UTC, szymski wrote:This is *default* initialization, not per instance initialization. The compiler will create one instance of B and it will become the default initializer of b in *every* instance of A. You can verify that with this: class B {} class A { B b = new B; } void main() { auto as = [new A, new A, new A]; assert(as[0].b is as[1].b); assert(as[1].b is as[2].b); assert(as[0].b is as[2].b); } Here, all of the asserts will pass. But add a constructor to A that does this: this() { b = new B; } And now the first assert will fail. This is *per-instance* initialization.class A { B b = new B(); }
Mar 19 2016
On Sunday, 20 March 2016 at 02:21:51 UTC, Mike Parker wrote:On Saturday, 19 March 2016 at 20:24:15 UTC, szymski wrote:default initialization worked like per instance initialization.This is *default* initialization, not per instance initialization. The compiler will create one instance of B and it will become the default initializer of b in *every* instance of A. You can verify that with this: class B {} class A { B b = new B; } void main() { auto as = [new A, new A, new A]; assert(as[0].b is as[1].b); assert(as[1].b is as[2].b); assert(as[0].b is as[2].b); } Here, all of the asserts will pass. But add a constructor to A that does this: this() { b = new B; } And now the first assert will fail. This is *per-instance* initialization.class A { B b = new B(); }
Mar 20 2016
On Sunday, 20 March 2016 at 09:53:07 UTC, szymski wrote:default initialization worked like per instance initialization.When coming to a new language, it's natural to use the idioms you're used to. That isn't always going to work the way you expect. If you're lucky, you'll see compiler errors. Otherwise, you'll find yourself scratching your head at odd behavior. When you encounter such situations in D, the answer is often in the documentation or somewhere here in the forum
Mar 20 2016