-4

I'm getting into exceptions on C++ right now, and I noticed a character I used before, but not like this. It's the & sign, used by cplusplus.com as: catch (exception& e)

While I used it with pointers like this before: pointer = &var which gave the pointer the the var variable's location.

What is different in the two uses of the & character, if they are different at all?

KvB
  • 79
  • 9

3 Answers3

8

There are three meanings of &:

  • Bitwise AND (binary operator)

    0x010 & 0x100 == 0x110
    
  • Address-of (unary operator)

    int  x = 42;
    int* p = &x;
    
  • Reference (when part of a type)

    int  x = 42;
    int& r = x;
    

You're looking at the latter.

This is not specific to exceptions; it just means that you're catching a reference to the object that was thrown as an exception. This means you don't need to copy the exception object, which increases the safety of your code, especially given that it's currently handling an unexpected (or "exceptional") scenario.

Time to read that C++ book of yours…!

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

They're different.

pointer = &var;

says that pointer gets the address of var.

catch (exception& e)

says that when e is passed in, we won't make a copy of it, but pass in the thing itself.

We use this commonly in function parameters:

void mySwap (int& a, int& b) ...

...

mySwap (x, y);

We pass in x for a and y for b, but we don't pass in copies as we would if there were no &; we pass in x and y themselves. (Technically, we pass it by "reference," but that's what it amounts to.) This is essential if we want x and y to be changed, but it's also a handy way of not going to the trouble of making a copy. If you want to skip making a copy but not make the parameter changeable, use const:

void myFunction (const Type& thingThatMustNotChanged);
Topological Sort
  • 2,733
  • 2
  • 27
  • 54
  • IMO it's better to think about references as a pointer you use like a regular object. Just like pointers, you can have a reference to an object that's no longer there. And depending on the usage many times references will compile into pointers. – David Feb 06 '15 at 15:17
  • 1
    @Dave: _"Just like pointers, you can have a reference to an object that's no longer there."_ No. I mean, you can physically get to that situation when you've messed up, but only after you're already violated the preconditions of the C++ language such that you're not writing it any more. So, in C++, it is not possible. – Lightness Races in Orbit Feb 06 '15 at 15:20
  • @LightnessRacesinOrbit preconditions of the C++ language? You'll have to elaborate. It's almost as easy to do as it is to do with a pointer - the only precondition it breaks is whatever you make up within your own program. `auto a = make_unique(); A& b = *a; a.reset();` - there's nothing broken there, yet. – David Feb 06 '15 at 15:28
  • I think I understand you. But we're dealing with a beginner here. I'd hate to confuse him by saying, "It's a lot like a pointer" (which he may not understand yet anyway) "except not completely." – Topological Sort Feb 06 '15 at 15:31
  • 1
    @Dave: Nonsense. You have a dangling reference. – Lightness Races in Orbit Feb 06 '15 at 15:31
  • @WillBriggs You're right. Thinking of references as pointers causes a lot of confusion. People who promote that line of thinking often don't understand references in the first place. – juanchopanza Feb 06 '15 at 15:52
  • @LightnessRacesinOrbit It's not broken until you use it. Dangling pointers and references are perhaps an expected state depending on deletion order of your objects. _Having_ one is not breaking any language precondition, and it's only a bug in your own code if you don't know it's dangling. – David Feb 06 '15 at 21:03
0

In C++, the operator '&' can be overloaded. This means that the same operator can have different meanings in different contexts. There are many operators in C++ that can be overloaded.

The '&' operator usually has 3 meanings:

In the reference case:

int val1 = 2;
int &rval = val1;

In the above case

rval 

Is made a reference to

val1

This means that any use of

rval

Is actually the use of

val1

Note: A reference is NOT an object. This means that a reference does NOT occupy any space in memory and, a plain reference can ONLY be bound to a non-const object. But not to a const object, a literal or the result of an expression.

Now in the pointer case :

int val1 = 2;
int *ptr = &val1;

In this case the address of 'val1' is stored in 'ptr'. But a pointer is an object which means that when we use the dereference operator '*' we're using the pointed to value. But when we don't we're using the pointer.

*ptr = 55 // pointed to value is changed 
 ptr = p; // the pointer's own memory

*And last but not the least, used as a bitwise operator:

A bitwise operator works with the binary digits(i.e, 0s and 1s). When we use the '&', this means that we're using the bitwise 'and' operator. This is a binary operator which means that it works with two operands. Here 'bitwise and' operator tests whether both the bits contain the binary digit '1', if so then the result is 1 else it is 0.

*not to be confused with the 'logical and' operator which contains two '&&'.