7

I have read on SO that open array parameters are passed by reference automatically. Is this the same thing for classes and strings or I have to use the var?

I refer to the fact that I want to pass to a function (or procedure) a parameter by reference. Like in C++ I always pass std::string& for example, it is explicit otherwise I pass a copy

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Raffaele Rossi
  • 2,997
  • 4
  • 31
  • 62
  • I removed question 1 from your original post. It is a dupe of http://stackoverflow.com/questions/14507310/whats-the-difference-between-var-and-out-parameters And it is strictly one question at a time here. Your other question is fine I think. – David Heffernan May 10 '17 at 11:16

1 Answers1

7

Your statement about open arrays is not correct. There are three forms of open array parameter:

procedure ByValue(arr: array of Integer);
procedure ConstParam(const arr: array of Integer);
procedure VarParam(var arr: array of Integer);

The final two forms, var and const, pass a reference to the array. However, the first, passing by value, passes a copy. If you want to avoid making a copy, then you should use either a var or const parameter. Choose between these depending on whether or not you wish the caller's array to be modified.

As for classes and strings, these types are reference types. Since they are already references, when you pass one to a procedure, you are passing the reference.

Let's look at the various possibilities for classes:

procedure ByValue(obj: TObject);
procedure ConstParam(const obj: TObject);
procedure VarParam(var obj: TObject);
procedure OutParam(out obj: TObject);

For ByValue and ConstParam, the reference is passed directly. The difference between the two is that in the implementation of ConstParam, the reference cannot be modified. It can in ByValue. The caller cannot see that modification. Of course, you can always call methods on obj that modify the state of the object. In practice there's little point in using const for a reference type.

For VarParam and OutParam, the address of the reference is passed. Thus the procedure receives a pointer to a pointer to the object. All of the pointer handling is hidden from you. But this is what allows you to modify the reference and have the caller see that modification.

Strings are also reference types, and so are handled similarly.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Ok now I have understood thank you, the pointer to a pointer thing is what I needed to be confirmed. Just last thing: records instead are NOT references like classes correct? – Raffaele Rossi May 10 '17 at 11:38
  • 1
    Classes are on the heap, records on the stack! So records are not reference types like classes. Delphi makes what you do in C++ using new – Alberto Miola May 10 '17 at 11:49
  • 1
    Records are value types, not reference types. But it is incorrect to state that they live on the stack. If dynamically allocated or contained inside classes, they are on the heap. – David Heffernan May 10 '17 at 12:20