digitalmars.D.learn - D Classes Passed By Reference or Value?
- Brandon Ragland (19/19) Aug 16 2015 Hi All, I'm a bit confused as to how Classes in D are passed in
- Alex Parrill (11/30) Aug 16 2015 Classes are reference types, a la Java/C#.
- Brandon Ragland (16/54) Aug 16 2015 Thanks,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (11/26) Aug 16 2015 As long as the returned object will be valid after the function leaves,
- Brandon Ragland (11/39) Aug 16 2015 If I understand you correctly than:
- Nicholas Wilson (31/79) Aug 16 2015 Yes.
- Alex Parrill (4/8) Aug 16 2015 This attempts to return a reference to the _variable_ `mc`, not a
Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new.... return mc; } The above fails, as "escaping reference to local variable" however, this was created using new.... Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandon
Aug 16 2015
On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote:Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new.... return mc; } The above fails, as "escaping reference to local variable" however, this was created using new.... Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandonclass MyClass { int x = 5; } void main() { auto c1 = new MyClass(); auto c2 = c1; c1.x = 123; assert(c2.x == 123); }
Aug 16 2015
On Sunday, 16 August 2015 at 22:35:15 UTC, Alex Parrill wrote:On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote:Thanks, That makes more sense. Though it does make the ref method signature unclear, as it only applies to literals at this point? Would you still need the ref signature for method parameters for classes to avoid a copy? Such that I could work on the class itself, and not a copy. //This is reference? void doStuff(ref MyClass mc){ return; } or would this also be a valid reference type: //This is a copy? void doStuff(MyClass mc){ return; }Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new.... return mc; } The above fails, as "escaping reference to local variable" however, this was created using new.... Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandonclass MyClass { int x = 5; } void main() { auto c1 = new MyClass(); auto c2 = c1; c1.x = 123; assert(c2.x == 123); }
Aug 16 2015
On 08/16/2015 04:13 PM, Brandon Ragland wrote:That makes more sense. Though it does make the ref method signature unclear, as it only applies to literals at this point?As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc.Would you still need the ref signature for method parameters for classes to avoid a copy? Such that I could work on the class itself, and not a copy.Obviously, you meant "the object itself."//This is reference? void doStuff(ref MyClass mc){ return; }Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.)or would this also be a valid reference type: //This is a copy? void doStuff(MyClass mc){ return; }That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali
Aug 16 2015
On Sunday, 16 August 2015 at 23:31:46 UTC, Ali Çehreli wrote:On 08/16/2015 04:13 PM, Brandon Ragland wrote:If I understand you correctly than: void doStuff(MyClass mc){ mc.x = 7; } Would be working with the reference to the object instantiated elsewhere. This would NOT be a copy of the object. That would mean that (ref MyClass mc) is the equivalent to a pointer to a pointer (sorta, though these are references, same idea follows). -BrandonThat makes more sense. Though it does make the ref method signature unclear, as it only applies to literals at this point?As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc.Would you still need the ref signature for method parameters for classes to avoid a copy? Such that I could work on the class itself, and not a copy.Obviously, you meant "the object itself."//This is reference? void doStuff(ref MyClass mc){ return; }Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.)or would this also be a valid reference type: //This is a copy? void doStuff(MyClass mc){ return; }That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali
Aug 16 2015
On Sunday, 16 August 2015 at 23:40:41 UTC, Brandon Ragland wrote:On Sunday, 16 August 2015 at 23:31:46 UTC, Ali Çehreli wrote:Yes. void doStuff(ref MyClass a, ref MyClass b, ref MyClass c, bool d) { if (d) b = a; else c = a; } void main(string[] args) { auto a = new MyClass(); a.x = 1; auto b = new MyClass(); b.x = 2; auto c = new MyClass(); c.x = 3; assert(a !is b); assert(a.x == 1); assert(a !is c); assert(b.x == 2); assert(c !is b); assert(c.x == 3); doStuff(a,b,c,true); assert(a is b); assert(b.x == 1); b.x = 2; assert( a.x == 2); assert(a !is c); assert(c.x == 3); doStuff(a,b,c,false); assert(a is c); assert(c.x == 2); }On 08/16/2015 04:13 PM, Brandon Ragland wrote:If I understand you correctly than: void doStuff(MyClass mc){ mc.x = 7; } Would be working with the reference to the object instantiated elsewhere. This would NOT be a copy of the object. That would mean that (ref MyClass mc) is the equivalent to a pointer to a pointer (sorta, though these are references, same idea follows). -BrandonThat makes more sense. Though it does make the ref method signature unclear, as it only applies to literals at this point?As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc.Would you still need the ref signature for method parameters for classes to avoid a copy? Such that I could work on the class itself, and not a copy.Obviously, you meant "the object itself."//This is reference? void doStuff(ref MyClass mc){ return; }Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.)or would this also be a valid reference type: //This is a copy? void doStuff(MyClass mc){ return; }That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali
Aug 16 2015
On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote:ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new.... return mc; }This attempts to return a reference to the _variable_ `mc`, not a reference to the class. Just remove `ref` from the function signature.
Aug 16 2015