views:

217

answers:

3

Hi All, I'm learning c++ coming from a java background (knowing a little C from many years ago)...

in Java, it's common practice to use "this" inside a constructor to distinguish the variable passed in as arguments to the constructor from the one declared in the class:

class Blabla {

    private int a;
    private int b;

    Blabla(int a, int b){
        this.a = a;
        this.b = b;
    }
}

I like this because the variable Blabla.a and the one passed in as argument to the constructor represent the same thing so it feels logical that they should have the same name...

Is it possible to do this in C++ ?

+2  A: 

Yes, you use this->a = a;

Also note that in C++ you should use initialization lists in your constructors.

class Blab 
{
    public:
        Blab(int a, int b)
           :m_a(a),
            m_b(b)
        {
        }

    private:
        int m_a;
        int m_b;
};

Edit:

You can use :a(a), b(b) in the initialization list using the same name for both your data member a and the parameter a passed into the constructor. They do not have to be different, but some feel that it is better practice to use a different naming convention for member variable names. I used different names in the example above to help clarify what the initialization list was actually doing and how it is used. You may use this->a to set another member variable if you wish. For example if both the member variables and the parameter variables are both a and b,

class MyClass
{
    public:
        MyClass(int a, int b);
    private:
        int a;
        int b;
};

// Some valid init lists for the MyClass Constructor would be
:a(a), b(b)       // Init member a with param a and member b with parameter b
:a(a), b(this->a) // Init member a with param a and init member b with member a (ignores param b)
:a(5), b(25)      // Init member a with 5 and init member b with 25 (ignoring both params)

It should be mentioned that initialization lists should init the member variables in the same order they appear in the class definition. A good compiler will give you warnings when you don't.

RC
Erm... You can't use `this->a` like that in an initializer list. The member being initialized has to be specified just by name: `Blab(int a, int b) : a(a), b(b) {}`
Steve Jessop
@Steve. Yea, I got "this" happy when I was writing the code. I have updated my answer
RC
You don't need the underscores, though: an initializer `a(a)` means "initialize the member `a` using the parameter `a`". Whether you get shot for it by your colleagues is another matter. Also, you can use `this` in the expressions, like `Blab(int a) : a(a), b(this->a) {}`
Steve Jessop
@Steve. Yes I know the underscores are unnecessary. I don't typically use them though I did it in this case to make it more clear as to what was being done.
RC
so, I can either use this->a or change the name of the variable slightly, i.e. add a trailing '_' or a leading 'm_' ?
DavidM
I updated my answer in order to answer your comment.
RC
+1  A: 

Since in C++ this is a pointer, you access its member variables using this->var.

Do note that C++ tends to have different conventions than Java, and it's common to use _var for private variables, instead of the usual Java way of this.var. Of course, it depends on the convention you want to use.

Tordek
although i'd argue m_* is used a shed sight more than _*. It really doesn'tmatter though.
Goz
@Goz:MS uses m_*, so people accustomed to their tools/frameworks frequently do the same. Quite a few others use *_ instead. In any case, `this->*` is quite unusual, and IME, almost qualifies as a code smell -- most such code seem to be relatively poor.
Jerry Coffin
Actually, using names such as _var is not a good idea. Leading underscores are reserved for the compiler and library implementers (technically, the rule has more details like, for example, two leading underscores and a capital letter, a single leading underscore, etc)
ltcmelo
Leading "_" is reserved by the standard for use by the compiler implementation. Not a valid choice for this use. I usually see trailing "_" used if not leading "m_".
Steve Fallows
`_var` is fine as long as `var` starts with a lower case letter. But the convention _* might be worth avoiding simply so that people who want an "initial" uppercase letter don't try `_Var`, which is reserved.
Steve Jessop
+5  A: 

Yes, you can use this to refer to member variables. That said, you'll often find that your code looks as follows in idiomatic C++:

class Blabla {
  private:
    int a_;
    int b_;

  public:
    Blabla(int a, int b) : a_(a), b_(b) {}
};

As you can see, you normally do not apply the access control specifiers (public, protected or private) to each member, but you group them in sections.

Also, if you use the type of initialisation that you used above, the members get initialised twice - once with the default constructor when the object is created (basically, before the code inside the curly brackets is executed) and the second time during the assignments to this->a.

Timo Geusch
Agreed, but I would expect an optimising compiler to avoid double-initialisation.
Robert Tuck