0

Can a C++ class member function's argument have the same identifier (name) as a member data of the same class?

My method for dealing with this was to use the this pointer, however I am not sure the code will compile as expected;

For example:

class M {

    [public/private:]
    int i;

    void add(int i)
    {
        (this->i) = ((this->i) + i);

        return;
    }
}

Quite a strange example, but it demonstrates the principle. Are the parentheses required?

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • 1
    The parentheses are not required in your example. In fact, I'd say they harm readability. – T.C. Aug 10 '14 at 11:07
  • @T.C. Thought they were not, but couldn't be sure. – FreelanceConsultant Aug 10 '14 at 11:09
  • It's still bad style. Try not to hide names like that. (Personally, when I need a parameter and a member to have the same name, a common occurrence in constructors, I add a `_` suffix to the end of he parameter name.) – Mike DeSimone Aug 10 '14 at 11:23
  • @MikeDeSimone I was doing that at one point, it is a good solution. However I started to get confused when I started using an `_` before the name for member data. That results in difficult to read statements such as `_pointer_to_b = pointer_to_b_` or worse, if returning values through arguments `pointer_to_b_ = _pointer_to_b`. Now that's confusing. – FreelanceConsultant Aug 10 '14 at 11:26
  • @user3728501: That's why people who feel the need to prefix members use the `m_` prefix instead. Also, `_`-prefixed symbols are sometimes reserved by libraries. – Mike DeSimone Aug 10 '14 at 21:38
  • @MikeDeSimone Indeed, however then you have an ugly "m" to look at all day, not very inviting... – FreelanceConsultant Aug 10 '14 at 22:17
  • A leading underscore is just as ugly. I don't use either. IMHO, if you need coding conventions to tell the difference between class members and local variables or parameters, your class and/or method is too complex and should be refactored. – Mike DeSimone Aug 11 '14 at 01:58

4 Answers4

2

As Jarod42 told you, the code is valid without parentheses.

An alternative way, not using this is to use scope resolution operator :: :

class M {

public:
    int i=0;   // better initialize it, if you do not have a constructor. 

    void add(int i)
    {
        M::i = M::i + i;  // the i belonging to class M vs. parameter i 

        return;
    }
};
roalz
  • 2,699
  • 3
  • 25
  • 42
Christophe
  • 68,716
  • 7
  • 72
  • 138
1

The code is valid, and parentheses are not required.

In addition, you may also have

class M
{
public:
    explicit M(int i) : i(i) {} // initialize member with method argument as expected.

private:
    int i;
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

your code is correct, but you could just use:

void add(int i) {
    this->i += i;
}

as you don't need parenthesis, also the += doesn't make it look so ugly. And btw: you don't need an explicit return statement as the method returns upon completion automatically.

xmoex
  • 2,602
  • 22
  • 36
0

however I am not sure the code will compile as expected;

Why don't you just try it?

Anyway, the answer is: yes, it will.

It's just that if you run into this problem very often, chances are that your identifiers could be longer or more descriptive. i is hardly an acceptable name for a function parameter or member variable.

You will also find that many coding standards require you to distinguish member variables from function parameters, e.g. by prepending all member variables with m_. In that case, your i member variable would become m_i. These are stylistic issues, with the potential of creating heated discussions.

The parentheses in your example are redundant. Sometimes, redundant parentheses enhance readability of code, but in this case I don't think so. And of course, using the += operator further simplifies the code:

void add(int i)
{
    this->i += i;

    return;
}
Christian Hackl
  • 27,051
  • 3
  • 32
  • 62