views:

498

answers:

8

OK I am not a very experienced C++ programmer, but I was wondering what is the significance of the underscores in the arguments of the following constructor?

class floatCoords
 {
 public:
  floatCoords(float _x, float _y, float _width, float _height)
   : x(_x), y(_y), width(_width), height(_height)
  {

  }
  float x, y, width, height;
  ...
+1  A: 

They are just names for parameters passed in. They happen to match member variables and are used for initializers.

There is no special meaning - it is just a convention some people may use.

Tim
+7  A: 

Nothing special. He just named it like that to distinguish between the member variables and parameter names.

Underscore is a valid character in C++ identifiers.

Mehrdad Afshari
Also, normally the member variables have underscores by convention and the constructor arguments don't. It is all really up to the local coding convention though. Some shops require "m_" in front of members. Stay away from double underscores though (reserved for compiler usage).see: http://stackoverflow.com/questions/1228161/why-use-prefixes-on-member-variables-in-c-classes
bluehavana
I've seen enough code to say that nothing in the names of private members, much less underscores, are conventional.
coppro
Also note that this distinguishing is not strictly necessary in a ctor-initializer - the name lookup for members only finds members, and the name lookup inside the initializer will find the parameter name first.
coppro
Like I said, local conventions: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Variable_NamesGuess @coppro meant in general though. Which is right.
bluehavana
A: 

They don't have a syntactic meaning. However, if you have a bunch of fields (e.g. x, y, width, and height), it's a common convention to name the constructor parameters that initialize them with the field name plus a leading underscore.

David Seiler
A: 

The purpose of those underscores is to distinguish the parameter variable float _x and the member variable float x. Syntactically, there's no special meaning added due to the underscores. I personally prefer to prefix all parameters with a_ and prefix all member variables with m_ when I do have to code C++.

So when I do get into a situation where I have to mix and match local, member, and parameter variables, I know which ones I am dealing with.

int y = a_x * 2;
m_x = y + 3;
eed3si9n
+7  A: 

It's just a convenient naming convention, it means nothing to the language. Just be sure you don't follow it with an upper-case letter: http://stackoverflow.com/questions/1449181/what-does-double-underscore-const-mean-in-c

Mark Ransom
Also see: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797
Martin York
@Martin: Thanks, I like your link even better.
Mark Ransom
I avoid leading underscores altogether just so I don't have to explain/remember the "don't follow with an upper-case letter" bit.
Dan
+5  A: 

Most likely, the author of the code was trying to avoid the potential conflict between the data member names and constructor parameter names in the initializer list. Quite likely, the author was not aware of the fact that C++ lookup rules make sure that the conflict will not occur anyway. I.e. the following code will also produce expected results

class floatCoords    {
    public:
        floatCoords(float x, float y, float width, float height)
                : x(x), y(y), width(width), height(height)
        {
        }
        float x, y, width, height;
        ...

although it might prove to be confusing for an unprepared reader.

Of course, inside the body of the constructor, parameter names will hide the member names, thus making it necessary to use this->... or qualified names to access the data members. Chances are the author of the code was trying to avoid that as well.

AndreyT
Interesting, did not know this tidbit. However, in my mind it would still be better to use parameter names that don't match member variable names. In this case, you can use x and y as parameters in the ctor, but were you to write setX and setY methods, you would have to use different parameter names. I prefer to keep my parameter names consistent throughout a class.
ThisSuitIsBlackNot
@ThisSuitIsBlackNot: Not necessarily. The `this->member` syntax let's you implement your `setX` and `setY` methods even if the parameter names hide the member names. Some coding standards actually require that class members are always accessed through `this->member` syntax (there's certain value in it, I have to admit).
AndreyT
@AndreyT: You make a good point. If used consistently, the this->member syntax is very clear (I've seen this format in many a Java class). However, what happens when you forget the "this->" part? I'm not sure what the behavior is, but I imagine this happens frequently on large projects. Even if nothing scary happens, the inconsistency in the code would bother me (I'm picking a nit here).
ThisSuitIsBlackNot
A: 

because if you would name den float x, float y etc. you could not access the actual fields of the class because they have the same name.

it has nothing to do with the language, it's just a convention by the actual programmer (to make the code more obvious, i think)

thbusch
A: 

These are just convention of variable naming that different people/institutions assume. This may seem unnecessary at first sight but is actually very useful when reading and writing code, especially when you have parameters and member variables that have the same name. E.g. you can commonly have these three cases:

class A {
  void foo(int age_) { //parameter
    int age = 18; //local scope
    if (age_ > age) cout << legal << endl;
  }
  int _age; //member
};

In the above example:

  • _variable - means this is a class member variable
  • variable_ - means this is a parameter to a function
  • variable - means this is just a regular variable local to the function scope
and _Variable tresspasses onto implementor namespace.
David Thornley