You are conceptually mixing up some things. A "
^
" syntax already means by reference.
Here is the illustration and the proof at the same time:
public ref class Port {
public:
Port(int initialBaudRate) : BaudRate(initialBaudRate) {}
int BaudRate;
};
public ref class PortUser {
public:
void ChangeBaudRate(Port^ port, int newRate) {
port->BaudRate = newRate;
}
};
int main(array<System::String ^> ^args)
{
PortUser portUser;
Port^ port = gcnew Port(2400);
portUser.ChangeBaudRate(port, 9600);
Console::WriteLine(L"New baud rate = {0}", port->BaudRate);
return 0;
}
Output:
New baud rate = 9600
That is the proof. If the function
ChangeBaudRate
worked with the (stack) copy of the
Port
instance, you would get the old value of 2400.
(Sorry my sample violates good incapsulation/visibility coding styles and makes little practical sense; it does not matter for the purpose of the illustration of by-reference parameters.)
In most aspects .NET
ref
types instantiated with
gcnew
behave like old-style C++ pointers. The major difference is that such pointers are volatile (underlying physical address may change) and are subject to Garbage Collection. The uniqueness of C++ in a set of all .NET languages is the ability to use value semantic with reference types. Example: the use of the
ref
class
PortUser
in the function
main
.
The operator "
%
" works much like "address" (i.e. the analog of old "
&
" operator). In this way it help transition from value to reference semantics. Consider the variant:
int main(array<System::String ^> ^args)
{
PortUser portUser;
Port port(2400);
portUser.ChangeBoudRate(%port, 9600);
Console::WriteLine(L"New boud rate = {0}", port.BoudRate);
return 0;
}
Now we're using value semantics for
port
instance, but in a call to
ChangeBoudRate
it again behaves like a by-reference parameter. 9600 again, to everyone's satisfaction :).
Thank you.
—SA