I know references are syntactic sugar, so easier code to read and write :)
But what are the differences?
Summary from answers and links below:
To clarify a misconception:
The C++ standard is very careful to avoid dictating how a compiler must implement references, but every C++ compiler implements references as pointers. That is, a declaration such as:
int &ri = i;
allocates the same amount of storage as a pointer, and places the address of i into that storage.
So pointer and reference occupies same amount of memory
As a general rule,
1) A pointer can be re-assigned:
int x = 5; int y = 6; int *p; p = &x; p = &y; *p = 10; assert(x == 5); assert(y == 10);
A reference cannot, and must be assigned at initialization:
int x = 5; int y = 6; int &r = x;
2) A pointer has its own memory address and size on the stack (4 bytes on x86), whereas a reference shares the same memory address but also takes up some space on the stack. Since a reference has the same address as the original variable itself, it is safe to think of a reference as another name for the same variable. Note: What a pointer points to can be on the stack or heap. Ditto a reference. My claim in this statement is not that a pointer must point to the stack. A pointer is just a variable that holds a memory address. This variable is on the stack. Since a reference has its own space on the stack, and since the address is the same as the variable it references. More on stack vs heap. This implies that there is a real address of a reference that the compiler will not tell you.
int x = 0; int &r = x; int *p = &x; int *p2 = &r; assert(p == p2);
3) You can have pointers to pointers to pointers offering extra levels of indirection. Whereas references only offer one level of indirection.
int x = 0; int y = 0; int *p = &x; int *q = &y; int **pp = &p; pp = &q;//*pp = q **pp = 4; assert(y == 4); assert(x == 0);
4) Pointer can be assigned NULL directly, whereas reference cannot. If you try hard enough, and you know how, you can make the address of a reference NULL. Likewise, if you try hard enough you can have a reference to a pointer, and then that reference can contain NULL.
int *p = NULL; int &r = NULL; <--- compiling error
5) Pointers can iterate over an array, you can use
++ to go to the next item that a pointer is pointing to, and
+ 4 to go to the 5th element. This is no matter what size the object is that the pointer points to.
6) A pointer needs to be dereferenced with
* to access the memory location it points to, whereas a reference can be used directly. A pointer to a class/struct uses
-> to access it's members whereas a reference uses a
7) A pointer is a variable that holds a memory address. Regardless of how a reference is implemented, a reference has the same memory address as the item it references.
8) References cannot be stuffed into an array, whereas pointers can be (Mentioned by user @litb)
9) Const references can be bound to temporaries. Pointers cannot (not without some indirection):
const int &x = int(12); //legal C++ int *y = &int(12); //illegal to dereference a temporary.
const& safer for use in argument lists and so forth.
The Python documentation seems unclear about whether parameters are passed by reference or value, and the following code produces the unchanged value 'Original'
class PassByReference: def __init__(self): self.variable = 'Original' self.Change(self.variable) print self.variable def Change(self, var): var = 'Changed'
Is there something I can do to pass the variable by actual reference?
Parameters are passed by value. The reason people are confused by the behaviour is twofold:
If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.
If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.
Okay, this is a little confusing. Let's have some examples.
Let's try to modify the list that was passed to a method:
def try_to_change_list_contents(the_list): print 'got', the_list the_list.append('four') print 'changed to', the_list outer_list = ['one', 'two', 'three'] print 'before, outer_list =', outer_list try_to_change_list_contents(outer_list) print 'after, outer_list =', outer_list
before, outer_list = ['one', 'two', 'three'] got ['one', 'two', 'three'] changed to ['one', 'two', 'three', 'four'] after, outer_list = ['one', 'two', 'three', 'four']
Since the parameter passed in is a reference to
outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.
Now let's see what happens when we try to change the reference that was passed in as a parameter:
def try_to_change_list_reference(the_list): print 'got', the_list the_list = ['and', 'we', 'can', 'not', 'lie'] print 'set to', the_list outer_list = ['we', 'like', 'proper', 'English'] print 'before, outer_list =', outer_list try_to_change_list_reference(outer_list) print 'after, outer_list =', outer_list
before, outer_list = ['we', 'like', 'proper', 'English'] got ['we', 'like', 'proper', 'English'] set to ['and', 'we', 'can', 'not', 'lie'] after, outer_list = ['we', 'like', 'proper', 'English']
the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The
the_list was a copy of the
outer_list reference, and we had
the_list point to a new list, but there was no way to change where
It's immutable, so there's nothing we can do to change the contents of the string
Now, let's try to change the reference
def try_to_change_string_reference(the_string): print 'got', the_string the_string = 'In a kingdom by the sea' print 'set to', the_string outer_string = 'It was many and many a year ago' print 'before, outer_string =', outer_string try_to_change_string_reference(outer_string) print 'after, outer_string =', outer_string
before, outer_string = It was many and many a year ago got It was many and many a year ago set to In a kingdom by the sea after, outer_string = It was many and many a year ago
Again, since the
the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The
the_string was a copy of the
outer_string reference, and we had
the_string point to a new list, but there was no way to change where
I hope this clears things up a little.
EDIT: It's been noted that this doesn't answer the question that @David originally asked, "Is there something I can do to pass the variable by actual reference?". Let's work on that.
As @Andrea's answer shows, you could return the new value. This doesn't change the way things are passed in, but does let you get the information you want back out:
def return_a_whole_new_string(the_string): new_string = something_to_do_with_the_old_string(the_string) return new_string # then you could call it like my_string = return_a_whole_new_string(my_string)
If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change): new_string = something_to_do_with_the_old_string(stuff_to_change) stuff_to_change = new_string # then you could call it like wrapper = [my_string] use_a_wrapper_to_simulate_pass_by_reference(wrapper) do_something_with(wrapper)
Although this seems a little cumbersome.
The title pretty much sums it.
From Understanding Weak References, by Ethan Nicholas:
A weak reference, simply put, is a reference that isn't strong enough to force an object to remain in memory. Weak references allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do it yourself. You create a weak reference like this:
WeakReference weakWidget = new WeakReference(widget);
and then elsewhere in the code you can use
weakWidget.get()to get the actual
Widgetobject. Of course the weak reference isn't strong enough to prevent garbage collection, so you may find (if there are no strong references to the widget) that
weakWidget.get()suddenly starts returning
A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are
WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while.
SoftReferencesaren't required to behave any differently than
WeakReferences, but in practice softly reachable objects are generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache, such as the image cache described above, since you can let the garbage collector worry about both how reachable the objects are (a strongly reachable object will never be removed from the cache) and how badly it needs the memory they are consuming.
And Peter Kessler added in the comments:
The Sun JRE does treat SoftReferences differently from WeakReferences. We attempt to hold on to object referenced by a SoftReference if there isn't pressure on the available memory. One detail: the policy for the "-client" and "-server" JRE's are different: the -client JRE tries to keep your footprint small by preferring to clear SoftReferences rather than expand the heap, whereas the -server JRE tries to keep your performance high by preferring to expand the heap (if possible) rather than clear SoftReferences. One size does not fit all.
I am intending this to be an entry which is a resource for anyone to find out about aspects of SQL that they may have not run into yet, so that the ideas can be stolen and used in their own programming. With that in mind...
What SQL tricks have you personally used, that made it possible for you to do less actual real world programming to get things done?
A fruitful area of discussion would be specific techniques that allow you to do operations on the database side, that make it unnecessary to pull the data back to the program, then update/insert it back to the database.
I recommend that you flesh out your answer where possible to make it easy for the reader to understand the value that your technique provides. Visual examples work wonders. The winning answer will have good examples.
My thanks to everyone who shared an idea with the rest of us.
This statement can save you hours and hours of programming
insert into ... select ... from
INSERT INTO CurrentEmployee SELECT * FROM Employee WHERE FireDate IS NULL; will populate your new table with existing data. It avoids the need to do an ETL operation or use multiple insert statements to load your data.
Why does the first return a reference?
int x = 1; int y = 2; (x > y ? x : y) = 100;
While the second does not?
int x = 1; long y = 2; (x > y ? x : y) = 100;
Actually, the second did not compile at all - "not lvalue left of assignment".
Expressions don't have return types, they have a type and - as it's known in the latest C++ standard - a value category.
A conditional expression can be an lvalue or an rvalue. This is its value category. (This is somewhat of a simplification, in C++11 we have lvalues, xvalues and prvalues.)
In very broad and simple terms, an lvalue refers to an object in memory and an rvalue is just a value that may not necessarily be attached to an object in memory.
An assignment expression assigns a value to an object so the thing being assigned to must be an lvalue.
For a conditional expression (
?:) to be an lvalue (again, in broad and simple terms), the second and third operands must be lvalues of the same type. This is because the type and value category of a conditional expression is determined at compile time and must be appropriate whether or not the condition is true. If one of the operands must be converted to a different type to match the other then the conditional expression cannot be an lvalue as the result of this conversion would not be an lvalue.
ISO/IEC 14882:2011 references:
3.10 [basic.lval] Lvalues and rvalues (about value categories)
5.15 [expr.cond] Conditional operator (rules for what type and value category a conditional expression has)
5.17 [expr.ass] Assignment and compound assignment operators (requirement that the l.h.s. of an assignment must be a modifiable lvalue)