-6
#include <iostream>
using namespace std;

class person {
public:
    int age;
    person(int v = 0) : age(v) {}
    friend const person & operator++(person &); //pref
    friend const person operator++(person &, int); //post
};

const person& operator++(person& a) {
    a.age++;
    return a;
}

const person operator++(person& a, int) {
    person aux = a;
    a.age++;
    return aux;
}

int main() {
    person p1(25), p2;
    p2 = ++p1;
    cout << p2.age<<endl;
    p2 = p1++;
    cout<< p2.age<<endl;
    cout << p1.age;
}

Maybe the person who wrote this piece used some 'extra slang' that isn't necessary or maybe I haven't read the manual enough but I don't understand the following:

What's the point of 'const' in here and what does 'person&' mean? The person &a or person& a in the () I think it means it gets passed by reference. Is it correct?

friend const person& operator++(person &a); 

Why here person doesn't have an & after it like above? I understand that the arguments are a reference and an int. But what int? I don't see it anywhere that function beign called like that, p1(25) in the int main() it's the constructor not a function. How does he know what to do when p1++ is invoked and when ++p is invoked. I know about overloading I just don't get it how that & after person in the first function works and what is the int in the second one. Thank you.

const person operator++(person& a, int)
erasmus77
  • 327
  • 1
  • 5
  • 16
  • 3
    Definitely you haven't read the "manual" enough. – Andy Prowl Jan 07 '14 at 20:13
  • Very useful, thanks Andy Prowl, another post incrementation for you. – erasmus77 Jan 07 '14 at 20:14
  • Many questions can be answered by reading the C++ FAQ: http://www.parashift.com/c++-faq/increment-pre-post-overloading.html] – Thomas Matthews Jan 07 '14 at 20:15
  • Thanks Thomas Matthews, excelent resource that site, parashift.com! It's good it has all overloading covered for other operators. – erasmus77 Jan 07 '14 at 20:19
  • @erasmus77: You may think it's not useful, but it is. The meaning of "&" is explained in every book on C++, as well as the way pre- and post-incrementation works. If you do not know what those things mean, then the most useful advice I can give you is to read more about it. – Andy Prowl Jan 07 '14 at 20:19
  • I know person& a and person &a are the same thing just as int *i and int* i are the same. I also know how pre and post incrementation works. It was just a bit unclear using classes. But regardless, I might be stupid, alas why do you reply not contributing at all? Just to be smart? I bet you are, you have 50000 points or whatever. You can just thumb down or report if this question disturbs you. – erasmus77 Jan 07 '14 at 20:22
  • @erasmus77: "Not contributing at all" is not what I did. What I did is giving you what I think is the right advice: "read more about it". I don't think I need to provide any specific links or book titles, a quick Google search (or even a search here on SO) would bring up a lot of material you can learn from. Also, my comment suggests that there is no "manual" of C++. There are books, tutorials, blogs, wikis, articles, Q&As and what not. Go find them. Not because I want to "be smart", but because this is what you need to do if you want to learn. – Andy Prowl Jan 07 '14 at 20:26

2 Answers2

1

The reason the pre-increment overload, i.e.

const person& operator++(person& a) // "const" is optional

returns a reference to a person (hence, the &) and the post-increment, i.e.

const person operator++(person& a, int)

returns a person, not a reference to a person (hence, no &) is that the state of the object returned from pre-increment is the same as the state of the object being operated on, while post-increment must return the object in its old state, i.e. before the increment.

Both operators leave the object passed in as the parameter in a changed state; the new state is the same for both objects. However, the post-increment must return the object in its old state, before the increment.

In order for that to work, a copy needs to be made. Once copying enter the picture, references are out: returning references to local objects is undefined behavior, so you are stuck with returning by value.

That is what the person aux = a; line is for: it creates a copy of the person in its state before the increment. Once the increment has been applied, the aux copy is returned to the caller. aux is a local variable, so it must be returned by value (i.e. no ampersand).

As far as the int is concerned, this is a syntactic convention introduced by the language designers. It looks somewhat bizarre on the first glance, but if you think of other options available to them (introducing a different keyword, adding a stand-in name for one of the overloads, etc.), the option they took no longer looks overly exotic.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • pre-increment does not need to be `const` -- post does need to be `const` to prevent meaningless assignment to a temp variable – Glenn Teitelbaum Jan 07 '14 at 20:43
  • @GlennTeitelbaum Technically, even the post does not need to be `const`, but it's a good idea to make it `const` precisely for the reason that you mentioned. I often make pre-increment `const` just for "symmetry", though. – Sergey Kalinichenko Jan 07 '14 at 20:46
0

person& a and person &a mean the same thing. I tend to do this too: Put it next to the type when only specifying a type, and putting it next to a variable when declaring a variable (or argument in this case). Yes, this means that while the syntax to work with a is the same as for non-pointers, this parameter is in fact passed as a reference (a pointer).

The purpose of const before a method is to indicate the method does not modify the class instance. This tells the compiler that it is safe to call this method on a const instance of the class.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • But in this case there's no point of it, right? There are no const instance of the class. – erasmus77 Jan 07 '14 at 20:16
  • @erasmus77: Classes are declared before instances of those classes are. A class should be written so it can be used in a wide variety of circumstances. By writing your class this way, it might be easier to use should there ever be a const instance of it created at any point in the future. Good programming is about making good designs that will work even for unexpected situations. It's just good practice. – Jonathan Wood Jan 07 '14 at 20:22