This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
References in VB.Net
I want to pass a medium large Customer db object, but I don't want to pass it by value, because I think it would be unnecessary.
In c++ when you had a large object it was inefficient to pass it by value, because a copy was created from it, so you passed it by reference so that there was no copy (of the object passed) created. I used to pass the parameter as a constant because that way if I tried to change the object inside the function the compiler wouldn't let me so that I wouldn't harm the passed object (because it was passed by reference). Is it possible to mimick this in vb.net or is it not needed?
My strong suspicion is that you're getting confused about how values are passed in VB.
If your CustomerDb type is a class, then every expression of that type will have a value which is already a reference. By default, that reference will be passed by value - but it's still only the reference which is passed, not a whole object.
If your CustomerDb type is a structure, then you really will be passing the whole value each time - and you should strongly consider changing it to a class anyway...
Of course, when you pass a reference by value, that doesn't stop the object from being modified within the method, but it does mean that changes to the parameter variable itself aren't reflected in the calling code.
Read my article on C# parameter passing - it's much the same in VB.
In .NET, classes (which I assume Customer is) are reference types. Passing a reference type as an argument will pass a reference (pointer) to the object. So passing a class is perfectly efficient and no copy is created.
If you pass a class by reference, then the method could change the reference (pointer) and it would be reflected in the calling method.
I don't know off the top of my head if there's an easy way to make the argument read only. Since reference types do pass a reference, any changes to the object will be reflected in the original. You might need a copy if you don't want the original to be modified.
Related
I noticed that when passing reference parameters to boost bind, those parameters won't act like references. Instead boost creates another copy of the member and the original passed in variable remains unchanged.
When I change the references to pointers, everything works ok.
My question is:
Is it possible to get references to work, or at least give a compiling error when it tries to use reference parameters?
The boost documentation for bind suggests that you can use boost::ref and boost::cref for this.
I ran into similar issue expecting a bind parameter to be passed by reference whenever the method used in the bind was declared to take a reference parameter. However this is NOT the case! You will need to explicitly wrap the bind parameter (that is to be passed by reference) in a boost::ref() or boost::cref() regardless of how the method is declared.
Example:
ClassA myClassAParameter
void Method(ClassA ¶m);
now, the following binding:
callback = boost::bind(&Method, myClassAParameter);
will actually make a COPY of the ClassA object (which i understand it is a temporary allocation and the called method should not keep a reference to it since this is not the reference of the actual object but to a copy of the object).
however, the following binding:
callback = boost::bind(&Method, boost::ref(myClassAParameter));
will not make a copy, but use a reference to create the bind object.
I'd like to work out conventions on passing parameters to functions/methods. I know it's a common issue and it has been answered many times, but I searched a lot and found nothing that fully satisfies me.
Passing by value is obvious and I won't mention this. What I came up with is:
Passing by non-const reference means, that object is MODIFIED
Passing by const reference means, that object is USED
Passing by pointer means, that a reference to object is going to be STORED. Whether ownership is passed or not will depend on the context.
It seems to be consistent, but when I want to pick heap-allocated object and pass it to 2. case parameter, it'd look like this:
void use(const Object &object) { ... }
//...
Object *obj = getOrCreateObject();
use(*obj);
or
Object &obj = *getOrCreateObject();
use(obj);
Both look weird to me. What would you advise?
PS I know that one should avoid raw pointers and use smart instead (easier memory managment and expressiveness in ownership) and it can be the next step in refactoring the project I work on.
You can use these conventions if you like. But keep in mind that you cannot assume conventions when dealing with code written by other people. You also cannot assume that people reading your code are aware of your conventions. You should document an interface with comments when it might be ambiguous.
Passing by pointer means, that object is going to be STORED. Who's its owner will depend on the context.
I can think of only one context where the ownership of a pointer argument should transfer to the callee: Constructor of a smart pointer.
Besides possible intention of storing, a pointer argument can alternatively have the same meaning as a reference argument, with the addition that the argument is optional. You typically cannot represent an optional argument with a reference since they cannot be null - although with custom types you could use a reference to a sentinel value.
Both look weird to me. What would you advise?
Neither look weird to me, so my advise is to get accustomed.
The main problem with your conventions is that you make no allowance for the possibility of interfacing to code (e.g. written by someone else) that doesn't follow your conventions.
Generally speaking, I use a different set of conventions, and rarely find a need to work around them. (The main exception will be if there is a need to use a pointer to a pointer, but I rarely need to do that directly).
Passing by non-const reference is appropriate if ANY of the following MAY be true;
The object may be changed;
The object may be passed to another function by a non-const reference [relevant when using third party code by developers who choose to omit the const - which is actually something a lot of beginners or lazy developers do];
The object may be passed to another function by a non-const pointer [relevant when using third party code be developers who choose to omit the const, or when using legacy APIs];
Non-const member functions of the object are called (regardless of whether they change the object or not) [also often a consideration when using third-party code by developers who prefer to avoid using const].
Conversely, const references may be passed if ALL of the following are true;
No non-mutable members of the object are changed;
The object is only passed to other functions by const reference, by const pointer, or by value;
Only const member functions of the object are called (even if those members are able to change mutable members.
I'll pass by value instead of by const reference in cases where the function would copy the object anyway. (e.g. I won't pass by const reference, and then construct a copy of the passed object within the function).
Passing non-const pointers is relevant if it is appropriate to pass a non-const reference but there is also a possibility of passing no object (e.g. a nullptr).
Passing const pointers is relevant if it is appropriate to pass a const reference but there is also a possibility of passing no object (e.g. a nullptr).
I would not change the convention for either of the following
Storing a reference or pointer to the object within the function for later use - it is possible to convert a pointer to a reference or vice versa. And either one can be stored (a pointer can be assigned, a reference can be used to construct an object);
Distinguishing between dynamically allocated and other objects - since I mostly either avoid using dynamic memory allocation at all (e.g. use standard containers, and pass them around by reference or simply pass iterators from them around) or - if I must use a new expression directly - store the pointer in another object that becomes responsible for deallocation (e.g. a std::smart_pointer) and then pass the containing object around.
In my opionion, they are the same. In the first part of your post, you are talking about the signature, but your example is about function call.
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 6 years ago.
I'm wondering if there is any difference between passing an object reference as a parameter or as an argument. Is the code below equivalent? Is there situations where I should use one or the other?
void foo(Object &object){
object.update()
}
Object object
foo(object)
VS
void bar(Object *object){
object->update()
}
Object object
bar(&object)
You seem a bit confused. None of your examples pass by value. First example passes by reference, the second passes by pointer.
The main differences are:
Pass by value foo(Object object): the function gets a copy of the argument and cannot change the original.
Pass by reference foo(Object& object): the function gets a reference (not copy) to the original object and can modify it. References cannot be "un-bound", they always refer to a valid object (with certain exceptions which are usually bugs).
Pass by pointer foo(Object* object): as passing by reference, except it is valid for the pointer to not refer to anything (it can be nullptr which is useful if you need to signal that).
When you take by reference and the function can be inlined, the compiler is - theoretically - not required to generate the address of the instance. Depending on your type, unary prefix operator&() might do more than just returning this. Also, it's valid for a pointer to be nullptr, you should check for that (or use gsl's not_null).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pass by Reference / Value in C++
I was wondering what the difference is between a call by value/reference/name. And why would it be beneficial to use one over another?
call by value: a copy of the parameters is passed to the function
call be reference: no extra copy is made, the caller's variable is passed directly.
Major difference is that one extra unnecessary copy is made in call by value paradigm... You should always use call be reference (or const reference) unless a callee needs to modify the variable and you don't want the changes to your caller's variable...
Call by value creates a copy of the argument which gets passed to the function - so for a large object that could create a large overhead. It also stops you making any changes to the argument inside the function as they will be reflected in the copy only. Call by reference passes a reference to the object and so changes can be made to that object - unless of course you pass by const reference.
I was told to change all pass by value or pass by reference arguments in a Qt/C++ application to pass by const reference. All Qt types (QString for instance) are concerned, but not native types (double, integer). Could you explain more precisely why, or point to reference?
Pass by value makes a local copy of the argument, so if a big structure is passed there might be quite a big loss of time and space. That's why big structures shall be passed by reference. But if the function/method really needs the copy of the parameter, then pass it by value.
On the other hand passing by reference makes the object vulnerable to changes - if the state of the object is changed in the function, the original object is modified since they are the same. That's why const reference is used: it prevents from changing/editing the object by mistake.
Another reason is polymorphism. When passing by value virtuality is lost, while passing by reference or pointer virtual methods work as expected.
When passing by reference we are passing the address of the same instance where pass by value involves copying of the object to another (via a copy constructor in case of QString) native types like int, double etc will be smaller in size so there is less overhead comparing QString like objects. By passing a const reference we ensure that the object will not get modified in the passed function as the changes made by the called function affects the object passed as both points to the same location.