3

Coming from python, where you would assign a member with the self keyword i wonder what the behaviour would be in C++ without using this keyword, since the compiler takes care of assigning members.

In other words, what happens when i do this:

class SomeClass
{
private:
    int someVariable;

public:
    void setSomeVariable(int someVariable);
};

void SomeClass::setSomeVariable(int someVariable)
{
    someVariable = someVariable;
}

Since the compiler does not complain i wonder if that is a correct way for writing accessors for members by convention and if the behaviour is determined( unlike for instance the evaluation of function arguments in C++)

tobilocker
  • 891
  • 8
  • 27
  • 3
    The behaviour is well determined, and very easy to test. – juanchopanza Feb 24 '16 at 10:39
  • 3
    You have to use `this->someVariable = someVariable;` to set the member instead of self assignation of the parameter. – Jarod42 Feb 24 '16 at 10:41
  • Is that also correct by convention without using `this` keyword? The comparison might be inappropriate but i was rather surprised, that the evaluation of arguments depends on the compiler. – tobilocker Feb 24 '16 at 10:41
  • @tobilocker no, none of this "depends on the compiler"; all of it is completely defined by the standard. the ambiguity is only in favour of the member when in the constructor initialisation list `: someVar{someVar} // inits member with local of same name`. anywhere else, you're just assigning the local to itself, which is of course pointless! – underscore_d Feb 24 '16 at 10:44
  • Related: http://stackoverflow.com/questions/10250016/should-i-use-the-same-name-for-a-member-variable-and-a-function-parameter-in-c, http://stackoverflow.com/questions/18042699/is-it-bad-to-have-the-same-name-for-parameter-as-for-member-variable, http://stackoverflow.com/questions/22832001/access-member-field-with-same-name-as-local-variable-or-argument – Cody Gray - on strike Feb 24 '16 at 10:45

4 Answers4

8

In your case, the class member someVariable is shadowed by the parameter passed into the function.

So your code is performing a trivial self-assignment: someVariable = someVariable is an expression that's equivalent to someVariable.

In order to disambiguate, use this->someVariable = someVariable;

(I will confess that I adopt the old-fashioned m_ prefix for class members, and s_ for static members. But that has fallen out of favour in recent years, and is pretty much a profanity in Java.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I prefer an `_arg` postfix for member function argument with same names as data members. – Revolver_Ocelot Feb 24 '16 at 10:46
  • I think it's a matter of taste but i am trying to avoid pre- or suffixes to maintain readability so i will go with the suggested 'this->someVariable'. Thanks. – tobilocker Feb 24 '16 at 10:56
  • That is indeed what the cool cats seem to do these days. Modern IDEs with their trendy syntax highlighting mean that class members stand out nicely enough. In the old vi days, that wasn't the case. – Bathsheba Feb 24 '16 at 10:57
  • I can't see how that depends on an IDE and at least this cool cat has put `syntax on` in his vimrc. But +1 for comment on Modern IDE's anyway. – tobilocker Feb 24 '16 at 11:18
3

If you do

void SomeClass::setSomeVariable(int someVariable)
{
    someVariable = someVariable;
}

The parameter someVariable will "hide" the member someVariable and so the setter fails. Do one of:

  1. Rename the parameter
  2. Apply a naming convention to members (e.g. mSomeVariable or someVariable_)
  3. User this->someVariable

All are equally valid, just down to personal preference.

John3136
  • 28,809
  • 4
  • 51
  • 69
3

The behaviour is determined, but it's not what you want. The function parameter is itself a variable, so the assignment:

someVariable = someVariable;

... simply sets the parameter value to its current value. To set the instance member, use:

this->someVariable = someVariable;

In the latter case, the this-> qualification forces the immediately following name someVariable to be resolved in the context of the class (specifically, the type of *this). On the other side of the assignment, someVariable is not qualified in such a way and so refers to the local parameter.

Of course, if the instance member is not shadowed by a local variable, there's no need to qualify it with this-> (which I think is what you meant by "the compiler takes care of assigning members", but that's really misattribution; the compiler simply does what the language standard requires of it. This is about how names are resolved to program elements, not about any special handling of members by the compiler).

davmac
  • 20,150
  • 1
  • 40
  • 68
0

do yourself a favour, and mark your member variables as member variables, e.g. by adding prefix _ or m_

class SomeClass
{
private:
    int m_someVariable; // now obvious a member variable

public:
    void setSomeVariable(int someVariable);
    void aStrangeGetter(int *someVariable);
};

void SomeClass::setSomeVariable(int someVariable)
{
    m_someVariable = someVariable; // member SET (you can instantly see this)
}
void SomeClass::aStrangeGetter(int *someVariable)
{
    *someVariable = m_someVariable; // no way to be misled
}
Tommylee2k
  • 2,683
  • 1
  • 9
  • 22