3

I have a class defined like this:

class MyClass 
{
    int x;
    public: 
        MyClass(int x); 
};

MyClass::MyClass(int x)
{ //Assign x here 
}

However, I can't initialize x in the constructor because it has the same name as an instance variable. Is there any way around this(other than changing the name of the argument)?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
Mike
  • 23,892
  • 18
  • 70
  • 90

9 Answers9

13

The best option is to use the constructor's initializer list:

MyClass::MyClass(int x) : x( x ) { // Body }

But you could also try this approach:

MyClass::MyClass(int x) { this->x = x; }
Naaff
  • 9,213
  • 3
  • 38
  • 43
  • @dirkgently GCC 4.2 doesn't complain about this... any reason that shadowing is bad? – Mike Feb 02 '10 at 19:46
  • 2
    @dirkgently -- shadowing might not be ideal, but it's valid C++. We could debate shadowing all day long, but what he wanted to know was C++ semantics. – Naaff Feb 02 '10 at 19:47
  • 5
    Seriously. You could not advice him to use a better name – Martin York Feb 02 '10 at 19:47
10

However, I can't initialize x in the constructor because it has the same name as an instance variable. Is there any way around this(other than changing the name of the argument)?

So change the name of the parameter!

class MyClass  
{ 
    int x; 
    public:  
        MyClass(int xInitVal);  
}; 

MyClass::MyClass(int xInitVal)
    :x(xInitVal)
{ // Don't assign x here.  
} 

By making the parameter name the same as a local you are just making the code hard to read.

Don't do it. Nearly every style guide you come across will tell you not to make parameters the same name as members.

JeffUK
  • 4,107
  • 2
  • 20
  • 34
Martin York
  • 257,169
  • 86
  • 333
  • 562
3

as an aside - you really should have a naming convention for your member variables that does not clash. This is usually coding rules 1 or 2 for c++ houses. Then when you see m_foo = bar you know exactly what is going on

we use

 int m_thingy;

I have also seen

 int _thingy;
 int thingy_

apologies in advance if you knew this and could not or would not do it

pm100
  • 48,078
  • 23
  • 82
  • 145
2

this->x = x;

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
2

You can use this to explicitly refer to the current object:

this->x = x;
sth
  • 222,467
  • 53
  • 283
  • 367
  • Seriously. You could not advice him to use a better name. And for more complex types that are not int this is the wrong answer anyway. – Martin York Feb 02 '10 at 19:50
  • How come that people with higher rep are laconically suggesting `this->x = x;` while people with lower rep are suggesting to rename the parameter? Superior technical knowledge vs common sense? :) – UncleBens Feb 02 '10 at 20:59
1

I strongly recommend you just change the variable names. Messing with duplicate identifiers is a fight without a cause.

In my code, I give all function parameters the prefix 'in' ("inValue"). I give all private member variables the prefix 'm' ("mValue").

TheBuzzSaw
  • 8,648
  • 5
  • 39
  • 58
0

Use this->x instead.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0

Use the this pointer

MyClass::MyClass(int x)
{
    this->x = x;
}

Of course not having colliding names like that in the first place would be a better solution.

Ruddy
  • 1,734
  • 10
  • 11
  • I guess this combines the worst of both worlds. There is no need for `this->x = x`, which is poor form. Also, as *Scott Meyers* states in his **Effective C++** series, "Prefer initialization lists in constructors." – Thomas Matthews Feb 02 '10 at 21:26
0

this->x = x isn't working? That's what we did (or used a different parameter name).

LH.
  • 101
  • 6