Hi

Please take a look at the following example:

Code:
```01	class Digit
02	{
03	private:
04	    int m_nDigit;
05	public:
06	    Digit(int nDigit=0)
07	    {
08	        m_nDigit = nDigit;
09	    }
10
11	    Digit& operator++(); // prefix
12	    Digit& operator--(); // prefix
13
14	    Digit operator++(int); // postfix
15	    Digit operator--(int); // postfix
16
17	    int GetDigit() const { return m_nDigit; }
18	};
19
20	Digit& Digit::operator++()
21	{
22	    // If our number is already at 9, wrap around to 0
23	    if (m_nDigit == 9)
24	        m_nDigit = 0;
25	    // otherwise just increment to next number
26	    else
27	        ++m_nDigit;
28
29	    return *this;
30	}
31
32	Digit& Digit::operator--()
33	{
34	    // If our number is already at 0, wrap around to 9
35	    if (m_nDigit == 0)
36	        m_nDigit = 9;
37	    // otherwise just decrement to next number
38	    else
39	        --m_nDigit;
40
41	    return *this;
42	}
43
44	Digit Digit::operator++(int)
45	{
46	    // Create a temporary variable with our current digit
47	    Digit cResult(m_nDigit);
48
49	    // Use prefix operator to increment this digit
50	    ++(*this);             // apply operator
51
52	    // return temporary result
53	    return cResult;       // return saved state
54	}
55
56	Digit Digit::operator--(int)
57	{
58	    // Create a temporary variable with our current digit
59	    Digit cResult(m_nDigit);
60
61	    // Use prefix operator to increment this digit
62	    --(*this);             // apply operator
63
64	    // return temporary result
65	    return cResult;       // return saved state
66	}
67
68	int main()
69	{
70	    Digit cDigit(5);
71	    ++cDigit; // calls Digit::operator++();
72	    cDigit++; // calls Digit::operator++(int);
73
74	    return 0;
75	}```

I have three questions.

1) When overloading the postfix operators ++/--, we add the dummy integer variable. Is there any reason why postfix was chosen to need this dummy variable, and not the prefix?

2) When using x++ (where x is an instance of a class), then does the compiler automatically add the dummy integer? So it calls x++ as x.operator ++(0), e.g.?

3) When returning the *this-pointer, they use

Code:
`Digit& operator++(); // prefix`
Why do they include the &? We have had lengthy talks about this, and we agreed that *this is a pointer (by type), but acts like a reference. So personally I would not include the ampersand. What do you say?

Best,
Niles.

2. Originally Posted by Niels_M
1) When overloading the postfix operators ++/--, we add the dummy integer variable. Is there any reason why postfix was chosen to need this dummy variable, and not the prefix?
The choice may well have been arbitrary, but it could also have been foresight that a typical implementation of prefix operator++ is not less efficient than a typical implementation of the corresponding postfix operator++, so the prefix form is better, all else remaining equal.

Originally Posted by Niels_M
2) When using x++ (where x is an instance of a class), then does the compiler automatically add the dummy integer? So it calls x++ as x.operator ++(0), e.g.?
Yes.

Originally Posted by Niels_M
Why do they include the &?
It is generally more efficient to return by reference where feasible.

3. Originally Posted by laserlight
TIt is generally more efficient to return by reference where feasible.

Thanks. Why is that the case?

Also, I have a question on returning references. Instead of creating a new thread, I thought I could just post it here. Please look at

Code:
```double &GetSomeData() {
double h = 46.50;
double &hRef = h;
return hRef;
}

double &GetSomeData() {
double h = 46.50;
return h;
}```
What is the difference between these two functions? In the second case, I do not believe it is obvious that we are returning a reference. But in the first case, I cannot see why we use the & in front of the double, since hRef is still a double.

Best,
Niles.

4. You return by reference where feasible to avoid copying the object.

One reason to avoid copying that relates to operator overloading is that you would not ordinarily want to copy the object that is being changed by operators. Using references makes it clear that all the changes are happening to the same object.

Another reason you might want to avoid copying in the first place is because copying is sometimes computationally expensive. Say you have a vector of 1 million phrases for a Wheel of Fortune game, or any similar amount of data. You would not necessarily want to copy that around in separate instances too often, if you were faced with the choice, simply because it takes too long. It might take undue resources away from graphics processing or something else.

I think "where feasible" needs particular emphasis though, because the examples you have shown are returning a reference to a local variable, which is not feasible because it makes the program undefined. Even if it seems to work, the code may not work as you intend on another compiler or even (sometimes) if you only use different switches.

5. Originally Posted by Niels_M
Also, I have a question on returning references. Instead of creating a new thread, I thought I could just post it here. Please look at

Code:
```double &GetSomeData() {
double h = 46.50;
double &hRef = h;
return hRef;
}

double &GetSomeData() {
double h = 46.50;
return h;
}```
What is the difference between these two functions? In the second case, I do not believe it is obvious that we are returning a reference. But in the first case, I cannot see why we use the & in front of the double, since hRef is still a double.
Neither of those functions are legal. They both return a reference to a local variable. So there is no difference between them.

Originally Posted by Niels_M
Why do they include the &? We have had lengthy talks about this, and we agreed that *this is a pointer (by type), but acts like a reference. So personally I would not include the ampersand. What do you say?
No, this is a pointer, *this is what it points to.

As said, you return by reference when it is desireable and feasible to avoid copying the object. Postincrement cannot avoid copying, but preincrement can.

6. You seem to be somewhat confused by the difference between a & that denotes a reference variable and a & that is the address-of operator. You might want to review this topic in your favorite C++ resource.

7. Originally Posted by CornedBee
You seem to be somewhat confused by the difference between a & that denotes a reference variable and a & that is the address-of operator. You might want to review this topic in your favorite C++ resource.
I feel pretty confident in distinguishing between these two things. As an example:

Code:
```int test_func_one() {
int a = 2;
return a;
}

int* test_func_two() {
int a = 2;
return &a;
}

int& test_func_three() {
int a = 2;
return a;
}```
The thing that I find is not odd in the three functions in what happens in test_func_three. In test_func_one and test_func_two, the return-type (int and int*, respectively) are precisely what we have in return a and return &a, respectively. In test_func_three we have return a, but a is not a reference. So the compiler creates a reference to a, and copies that to the caller. That is what I find to be somewhat different than usual, i.e. that the compiler is doing something behind our backs when returning references.

8. Ah, the wonderful mismatch between variable types and expression types in C++. Yes, it's confusing.

The simple (but not really correct) explanation is that the compiler automatically creates references when they are required by the context and the value in question allows it. If you're not interested in the technical details, you need read no further.

The complicated, confusing, but correct answer is that there's really two sides to the type system in C++.
First, there's the types as you write them. 'int' is a written type. So are 'int*' (pointer to int) and 'int&' (reference to int). Written types are relevant in variable declaration, return types and casts.
Second, there's the types of expressions. The important thing is that an expression *never* has a reference type. That is, even if you have this:
Code:
```int i = 0;
int &ri = i;
foo(ri);
int x = ri + 3;```
all usages of ri have type 'int', not type 'int&', even though the variable ri has type 'int&'. But the usage of ri is an expression and thus cannot have reference type.
The same doesn't apply to pointer types, because pointers are objects in the C++ terminology, unlike references, which are, well, references. In other words, the expression &i has type 'int*'.
However, expressions have an additional property that is unique to expression types: value category. An expression can be an lvalue or an rvalue. (In C++0x, it can be an lvalue, xvalue or prvalue, but let's not get too confusing.)
Literals, most function results, the results of most built-in operators, the results of most casts, and some more are rvalues. Rvalues are values that do not really have a location in memory. (Also not entirely correct, but we'll ignore this again as too complicated.)
Variables, the results of functions that have reference return types, the result of casts to reference types, the result of the pointer dereference operator, and the result of the array index operator are lvalues. Lvalues kinda have a memory location. Lvalue-ness is easily discarded if the context is only interested in the actual value. (E.g. in the addition in the code snippet above, the lvalue-ness of the ri expression is discarded, because + doesn't care about it.)
Now, some contexts require lvalues. The address-of operator & needs an lvalue as its argument. (That's why &5 is illegal.) Initialization of references (whether as part of variable initialization, return value initialization, or function argument initialization) needs an lvalue, with an exception rule. Cast to reference needs an lvalue. A few other contexts, too.
The exception rule, by the way, is that references to const (e.g. 'const int&') can be initialized with rvalues, by creating a temporary memory location and copying the value there.

Rvalue references in C++0x make this a little more complicated, but this is the gist of it in C++03.

So to explain the example you have, in func_one, the return expression is 'lvalue of int'. Because the return type is 'int', the lvalue-ness is discarded, and the function result is 'rvalue of int'.
In func_two, the return expression is 'rvalue of int*' (the result of & is an rvalue). An rvalue is exactly what the return type wants, so the function result is also 'rvalue of int*'. As a side note, said pointer points to an invalid memory location the moment the function returns.
In func_three, the return expression is 'lvalue of int'. The return type is 'int&', so you actually need that lvalue-ness. The reference binds to the lvalue. Because the return type is a reference, the function result is 'lvalue of int'. Again, though, the reference is invalidated the moment the function returns, so actually using the return value is illegal.

9. Originally Posted by CornedBee
Ah, the wonderful mismatch between variable types and expression types in C++. Yes, it's confusing.

The simple (but not really correct) explanation is that the compiler automatically creates references when they are required by the context and the value in question allows it. If you're not interested in the technical details, you need read no further.

The complicated, confusing, but correct answer is that there's really two sides to the type system in C++.
First, there's ... is illegal.
Ah, perfect. Thank you for taking the time to write this.

Best,
Niles.