www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing a string by reference

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
Do I understand correctly that in order for me to pass a string 
when creating an object, I must pass it by value? And if I have a 
variable containing a string, can I pass it by reference?

Should I always do constructor overloading for a type and a 
reference to it?
In the case of the variable `c`, a drop occurs. Why? An object is 
not being created on the stack?

```d
import std.stdio : writeln;

class A
{
     private string str = "base";

     this(ref string str)
     {
         writeln("type reference string");
         this.str = str;
     }

     this(string str)
     {
         writeln("type string");
         this.str = str;
     }

     this() {}

     void print()
     {
         writeln(str);
     }
}

void main()
{
     auto a = new A("Hello, World!"); // this type string
     a.print();
     string text = "New string";
     auto b = new A(text); // this type reference string
     b.print();
     A c;
     c.print();  // segmentation fault! Why not "base"?
}

```
Nov 08 2022
next sibling parent novice2 <sorry noem.ail> writes:
On Tuesday, 8 November 2022 at 12:30:50 UTC, Alexander Zhirov 
wrote:
     A c;
this declaration not creates class instance. you should use "new". btw, struct have other behavoiur
Nov 08 2022
prev sibling next sibling parent Hipreme <msnmancini hotmail.com> writes:
On Tuesday, 8 November 2022 at 12:30:50 UTC, Alexander Zhirov 
wrote:
 Do I understand correctly that in order for me to pass a string 
 when creating an object, I must pass it by value? And if I have 
 a variable containing a string, can I pass it by reference?

 Should I always do constructor overloading for a type and a 
 reference to it?
 In the case of the variable `c`, a drop occurs. Why? An object 
 is not being created on the stack?

 ```d
 import std.stdio : writeln;

 class A
 {
     private string str = "base";

     this(ref string str)
     {
         writeln("type reference string");
         this.str = str;
     }

     this(string str)
     {
         writeln("type string");
         this.str = str;
     }

     this() {}

     void print()
     {
         writeln(str);
     }
 }

 void main()
 {
     auto a = new A("Hello, World!"); // this type string
     a.print();
     string text = "New string";
     auto b = new A(text); // this type reference string
     b.print();
     A c;
     c.print();  // segmentation fault! Why not "base"?
 }

 ```
You forgot to assign "c" to anything, I think you meant: `A c = b;` Read that segmentation fault as null pointer exception. Whenever you assign something to `ref type something`, it will basically be the same as writing `myVariable = *something;` in C code, so, in that case, it won't make any difference. The `ref` attribute only means that if you change your string inside the code that takes by ref, it will reflect when returning, such as: ```d void modifyString(ref string input) { input~= "Now it is modified"; } string text = "New string"; modifyString(text); writeln(text); //"New stringNow it is modified" ```
Nov 08 2022
prev sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 8 November 2022 at 12:30:50 UTC, Alexander Zhirov 
wrote:
 Do I understand correctly that in order for me to pass a string 
 when creating an object, I must pass it by value?
You should almost never use `ref string`. Just use plain `string`. In fact, ref in general in D is a lot more rare than in languages like C++. The main reason to use it for arrays is when you need changes to the length to be visible to the caller... which is fairly rare.
 In the case of the variable `c`, a drop occurs. Why? An object 
 is not being created on the stack?
nope, an object isn't created there at all. you should use `new C`.
Nov 08 2022
next sibling parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
Thanks for answers!

On Tuesday, 8 November 2022 at 12:43:47 UTC, Adam D Ruppe wrote:
 You should almost never use `ref string`. Just use plain 
 `string`.
So it's always working with thick pointers?
 nope, an object isn't created there at all. you should use `new 
 C`.
If I create just `A c`, then is it an empty pointer?
Nov 08 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/8/22 04:53, Alexander Zhirov wrote:
 On Tuesday, 8 November 2022 at 12:43:47 UTC, Adam D Ruppe wrote:
 Just use plain `string`.
So it's always working with thick pointers?
Yes, D's arrays are fat pointers. strings are arrays of immutable(char).
 nope, an object isn't created there at all. you should use `new C`.
If I create just `A c`, then is it an empty pointer?
Yes. Classes are reference types in D. Class variables are implemented as pointers. Their default value is null. Ali
Nov 08 2022
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Tuesday, 8 November 2022 at 13:05:09 UTC, Ali Çehreli wrote:
 Yes. Classes are reference types in D. Class variables are 
 implemented as pointers. Their default value is null.

 Ali
Thanks! 🙂
Nov 08 2022
prev sibling parent IGotD- <nise nise.com> writes:
On Tuesday, 8 November 2022 at 12:43:47 UTC, Adam D Ruppe wrote:
 In fact, ref in general in D is a lot more rare than in 
 languages like C++. The main reason to use it for arrays is 
 when you need changes to the length to be visible to the 
 caller... which is fairly rare.
In general many parameters are passed as const, the called function never changes the parameter. Which brings the question, will the compiler optimize the parameter so that the string is only passed as a pointer underneath when it knows it is a const?
Nov 09 2022