When You Pass 'This' as an Argument

Why, or in what situations, would you pass an argument to a function as a reference (or pointer) in C++?

There are essentially three reasons why this is done.

Reduced memory usage

Every time you call a function the arguments are copied and passed. This isn't a big deal when you are passing around numbers. However when you are dealing with big chunks of memory, like objects, structs, arrays etc. this becomes very expensive.

So all complex types are typically passed as pointers. If you are throwing around objects you are always working with a pointer.

The const qualifier should be used in this instance to indicate that the variable won't be changed.

Modify the argument

Sometimes it is useful to modify the passed argument, though this should be avoided as bad style. The best example I think is modifying an array, for example a push() function. Another is modifying an objects public members, or when you want to return multiple values from a function.

Note that this can be a source of bugs. If you are modifying a passed variable it should be obvious from the name of the function that this is what you are doing.

Low level memory access

Anything which directly works with memory will want direct access to said memory. Standard practice in C but less common in C++. Look at functions like memcpy() and anything else from <string.h>.

Passing this as an argument - C#

Classes are reference types, so doing

Class B
{
public void Do(A classA)
{
//Manipulate
}
}

should manipulate the object classA references. Then in A,

Class A
{
B classB;

public A()
{
classB = new B();
}

public void Act()
{
B.Do(this);
}
}

Note: "This does have the side effect that the reference of A that you pass cannot be set to null (it will only set the local variable to null)" - JulianR

how to call a function passed as argument with its parameters already given in D?

In D, you can use a lazy function parameter for this.

import std.stdio;

void CALL(lazy void x) {
writeln("before called");
x;
writeln("after called");
}

void foo(int x, int y) {
writeln(x, " ", y);
}

void main() {
CALL(foo(3, 5));
}

D's lazy parameter storage class causes the compiler to wrap whatever you give it in a little anonymous function. The above is as if you wrote:

import std.stdio;

void CALL(void delegate() x) { // note delegate here in long-form syntax
writeln("before called");
x();
writeln("after called");
}

void foo(int x, int y) {
writeln(x, " ", y);
}

void main() {
// and this delegate too
CALL( delegate() { return foo(3, 5); } );
}

But the compiler rewrites it for you. This is why I said lazy void - the void there is the return type of the hidden function you pass. If it returned int, you could use lazy int instead.

Note that since x inside the CALL function is rewritten to be a hidden function, calling it twice will actually evaluate the arguments twice:

void CALL(lazy void x) {
writeln("before called");
x;
writeln("after called");
x;
writeln("after called again");
}

would do:

before called
3 5
after called
3 5
after called again

Notice how it printed out the arguments twice. Just like the C macro, actually. But if that's not what you want, simply assign it to a temporary yourself:

void CALL(lazy int x) {
auto tmp = x;
// you can now use tmp as a plain int
}

What's the difference between an argument and a parameter?

A parameter is a variable in a method definition. When a method is called, the arguments are the data you pass into the method's parameters.

public void MyMethod(string myParam) { }

...

string myArg1 = "this is my argument";
myClass.MyMethod(myArg1);


Related Topics



Leave a reply



Submit