46

I am a C++ noob and i've a problem of understanding c++ syntax in a code. Now I am quite confused.

class date
{
private:
int day, month, year;
int correct_date( void );
public:
void set_date( int d, int m, int y );
void actual( void );
void print( void );
void inc( void );
friend int date_ok( const date& );
};

Regarding to the '&' character, I understand its general usage as a reference, address and logical operator...

for example int *Y = &X

What is the meaning of an & operator at end of parameter?

friend int date_ok( const date& );

Thanks

edit:

Thanks for the answers. If I have understood this correctly, the variable name was simply omitted because it is just a prototype. For the prototype I don't need the variable name, it's optional. Is that correct?

However, for the definition of the function I definitely need the variable name, right?

kgui
  • 4,015
  • 5
  • 41
  • 53
snipor
  • 461
  • 1
  • 5
  • 5
  • It's a reference, which was in your list. Anyway, `&&` is the logical one. `&` is the bitwise one. – chris Jan 01 '14 at 00:38
  • 26
    it is not at the end of a _variable_, it is at the end of a _type_ – behzad.nouri Jan 01 '14 at 00:39
  • The declaration in question does not name the parameter. The name is completely omitted. The `const data` part is the type, meaning that `const data &` stands for a parameter of reference type. The parameter is left unnamed in this declaration. – AnT stands with Russia Jan 01 '14 at 01:24
  • 1
    You can also rewrite that line as `friend int date_ok(const date &dateParam);` if you want. The formal parameter dateParam in the declaration is just for documentation purposes and does not affect the operation of the function – Brandin Jan 01 '14 at 10:59

5 Answers5

59

const date& being accepted by the method date_ok means that date_ok takes a reference of type const date. It works similar to pointers, except that the syntax is slightly more .. sugary

in your example, int* Y = &x makes Y a pointer of type int * and then assigns it the address of x. And when I would like to change the value of "whatever it is at the address pointed by Y" I say *Y = 200;

so,

int x = 300;
int *Y = &x;
*Y = 200; // now x = 200
cout << x; // prints 200

Instead now I use a reference

int x = 300;
int& Y = x;
Y = 200; // now x = 200
cout << x; // prints 200
Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
33

In this context, & is not an operator. It is part of the type.

For any given type T, the type T& is a "reference to T".

The symbol & in fact has three meanings in C++, and it's important to recognise those different meanings.

  • "address of" when applied to an expression
  • "reference" when part of a type
  • "bitwise AND" when applied to two numbers

Similarly, * has at least three meanings, and once you've grasped those, you'll have pointers and references down. :-)

If I have understood this correctly, the variable name simply was omitted there because it is just the prototype. And for the prototype i don't need the variable name, it's optional. Is that correct?

Yes.

However, for the definition of the function I need definitely the variable name, right?

No. Although you'll usually want it (otherwise what's the point?!) there are some circumstances in which you don't, usually when you've only introduced the parameter to engage in overload-related trickery.

But speaking purely technically you can omit the argument name from the declaration and/or the definition as you wish.

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

So, for starters, I think you might be more confused in that the author of that code omitted something quite important (although optional): the variable name.

Let's rewrite that:

friend int date_ok( const date& check);

The type of the variable 'check' is const date&. We are passing it to the function as a 'constant reference'. In other words, it's an alias to whatever we passed in (via pointer magic), but we cannot modify it.

The reason that we do this is so that we can pass large objects (like a std::vector) into functions without making a copy of them. Pass by value incurs a copy operation. For an int, that doesn't matter (it takes next to no time), for a class, it might be more significant. The rule of thumb is to always pass objects by reference, and to pass them by const reference if you don't intend to modify them. (This rule of thumb ignores move semantics, but I'll assume you don't know about that yet).

Mark
  • 3,806
  • 3
  • 21
  • 32
1

using & at the end of a type in a function prototype allows passing-by-reference, instead of passing-by-value (copy). This way you can modify the date object in the friend function.

friend int date_ok( const date& );

Friend: In your class definition this mean that you're telling that a function date_ok can access to all parameters of your class. In deed it means that it is almost a member of your class, so consider adding this friend function rather as a member function. (unless you have other good reasons, like not polluting your class with foreign definitions)

If yes, also consider making that a static function, it could have all the same access to the guts of your date object class. But that would be more natural.

cf. the book "101 C++ coding standard". Prefer defining static member functions, it favours loose coupling.

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
0

Thanks for the answesers. If I have understood this correctly, the variable name simply was omitted there because it is just the prototype. And for the prototype i don't need the variable name, it's optional. Is that correct?

However, for the definition of the function I need definitely the variable name, right?

snipor
  • 461
  • 1
  • 5
  • 5