0

I came across a C++ struct definition with a constructor.

struct Foo                                                                                                                                                                                                                                   
{
    int x;

    Foo( int _x ) : x(_x)
    {   

    }   
    ~Foo()
    {   
        std::cout << "Destructing a Foo with x=" << x << "\n";
    }   
};

I know about member initializer but don't quite get what _x means here? Can someone please enlighten me?

liv2hak
  • 14,472
  • 53
  • 157
  • 270

3 Answers3

2

It means a variable named "_x". The underscore can be used in names of variables like letters, although identifiers whose names start with underscores have a long standing convention as being reserved for the compiler's library.

int _x;

Means the same thing that

int x;

means. Or "int a;", "int b;", or int anything. Variable names in C and C++ may start with underscores or letters, and consist of underscores, letters, and digits. Although, as I said, leading underscores should be avoided, as they're generally reserved for use by the compiler's library.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I have typically seen constants (integer in this example) in case of member initializer list.I thought the idea of member initalizer list is to implictly initialize the member variables. – liv2hak Feb 11 '16 at 00:45
  • 1
    Names that start with an underscore and are followed by an uppercase letter, or another underscore, are reserved for use by the implementation. Underscore and lowercase letter is fine. See [this answer](http://stackoverflow.com/a/228797/241631). (cc @liv2hak) – Praetorian Feb 11 '16 at 01:07
2

That's not kind of special or magic syntax. The prefixed _ is used to distinguish the constructor parameter from the member variable symbol. That's all.

Using a definition like

struct Foo {
    int x;
    Foo( int x ) : x(x) {}
};

would just be ambiguous scope wise.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • I have typically seen constants (integer in this example) in case of member initializer list.I thought the idea of member initalizer list is to implictly initialize the member variables. – liv2hak Feb 11 '16 at 00:49
  • 1
    @liv2hak Constructor parameters can be used as well in the member initializer list to implictly initialize member variables, they just need to have disambiguate symbol names from the members. – πάντα ῥεῖ Feb 11 '16 at 00:51
  • @πάνταῥεῖ Actually the names can be the same (although not a good coding style IMO), the compiler will resolve them correctly, as in `x(x)` it is clear that the first `x` refers to the member. Example [here](http://coliru.stacked-crooked.com/a/74193ff591911277). – vsoftco Feb 11 '16 at 01:05
  • @vsoftco Not every compiler gets that right from my experience. Disambiguating is better, as well as for the reader of the code, – πάντα ῥεῖ Feb 11 '16 at 01:06
  • @πάνταῥεῖ I am not 100% sure that it is standard compliant, although it probably is, since both clang and gcc accepts it. But again, I agree that it is not a good idea to use the same names. – vsoftco Feb 11 '16 at 01:07
  • @πάνταῥεῖ Looks like it's standard compliant (but bad coding style): http://stackoverflow.com/q/6185020/3093378. – vsoftco Feb 11 '16 at 01:10
0
Foo( int _x ) : x(_x)
{   

}

This is a constructor that takes an integer which is then used to initialize the value of member variable x.

Foo f(5);
// -> f.x = 5

The reason for the underscore is to disambiguate between the function parameter and the variable it's being assigned to.

YMMV: Many development teams use similar strategies:

. Prefix all member variables with "m_", . Prefix or suffix member variables with "_", e.g. _x, x_,

It's not very common but you'll find some development teams who always disambiguate function parameters with a prefix:

class Foo {
    int m_x; // member x
public:
    Foo(int _x) : m_x(_x) {}
    int x() const { return m_x; }
};

the advantage of this approach: you can have lowercase member function names which won't conflict with parameters, so you can have getters that aren't prefixed with 'get'.

kfsone
  • 23,617
  • 2
  • 42
  • 74