3

This is something I do quite commonly when I program C++, and I've been wondering for a while if its a "bad" habit (Is this behaviour standardized?)

Lets say I have a class:

Class Foo {
  public:
    Foo(int x) {
      //this->x is the member "x" of Foo
      //x is the paramater "x" to the function
      this->x = x; //Sets Foo::x to x (parameter x)
    }

  private:
    int x;


};

Notice how in Foo::Foo(int x), the parameter is named x which is the same name as a member variable for Foo.

I commonly just use use this->x = x; to assign the member variable the value of the parameter, which seems to work for me (I commonly use MSVC). In MSVC (and GCC I think), accessing x will access the parameter named x rather than the member named x. Is this standardized behaviour across all c++ compilers? Is there anything stopping compilers from associating just x with the member variable instead of the parameter variable? (eg: this->x; would be equivalent to this->x = this->x;)

Brad
  • 10,015
  • 17
  • 54
  • 77
  • 1
    You should use the initializer list instead of making an assignment. Using the initializer list you only init the member x once. In your current code x is initialized and then parameter x is assigned to it, essentially you are doing 2x work. – Barış Uşaklı Oct 18 '13 at 23:52

3 Answers3

5

Yes, using any compliant compiler, the parameter x will hide the member x. However a more interesting alternative to what you've written is this:

class Foo {
public:
    Foo(int x) : x(x) {}
private:
    int x;
};

which, aside from being unreadable, will actually do precisely what you want it to.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
5

I agree with Rob that any standards compliant compiler will let you do what you are doing but your code is difficult to read.

Naming conventions are very important. Pick a naming convention and never alter it in the same program.

I use this guide when programming in C++: http://geosoft.no/development/cppstyle.html This is a list of the most common naming conventions and each one includes a short statement on why that particular naming convention was selected. Copy this list and customize it to your liking.

Item #11 (Under Naming Conventions) addresses your question directly and gives you a MUCH better alternative.

Jason Enochs
  • 1,436
  • 1
  • 13
  • 20
  • 2
    +1, for excellent advice, even though this doesn't answer his question. He didn't ask "what should I do?", he asked "what does the compiler do?" I think he already knows he shouldn't do what he does. – Robᵩ Oct 18 '13 at 23:55
  • No, he first asked, "...is this a bad habit." There are actually three questions in his post. You covered the others. – Jason Enochs Oct 19 '13 at 00:01
  • 1
    @JasonEnochs I believe the OP implies it might be a bad habit if the behaviour is not standard, not that it might be a bad habit because it isn't a good style. However I can see that it is easily open to interpretation, so your answer is worthwhile. – JBentley Oct 19 '13 at 00:03
  • @JBentley The behavior is not standard or good style. Just because the compiler allows it, does not make it standard(common) nor does it suggest that it should be done. Readability is very important when deciding on a personal style. There are many possible techniques but the one he is using is too difficult to read (In my opinion). – Jason Enochs Oct 19 '13 at 00:10
  • 1
    @JasonEnochs You misunderstand me. When the OP asks "Is the behaviour standardised", he is worried that his assumption that `x` refers to the parameter and not the member variable, may not be standard compiler behaviour, and that he might run into trouble one day if a compiler decides to do the opposite with his code. _That_ is why he is worried it might be a bad habit. The question is not about coding styles. – JBentley Oct 19 '13 at 00:12
  • @JasonEnochs When I use the word "standard" I am referring to the C++ standards. There is no such thing as a "standard" when it comes to coding styles - there are merely guidelines and common practices. – JBentley Oct 19 '13 at 00:14
  • Both Rob and I stated in our answers that what he is doing IS compliant to the standards and any compiler should allow it. Sorry if I wasn't clear. – Jason Enochs Oct 19 '13 at 00:19
  • @JasonEnochs Yes sure. But I wasn't saying you didn't answer that part of the question. I was responding to your very first comment, the one under Rob's, where you claimed there are three questions in the post. I feel like we're going round in circles so I'm going to leave it at that. – JBentley Oct 19 '13 at 00:23
  • While your post might be considered off topic, I actually think that it is a great advice. The link is superb! – mzuther Jan 21 '16 at 19:31
1

Although the initializer list is probably the canonical approach, the order which the assignments occur is not under your control. But simply prepending 'm_' or '_' to your members is one approach used. Another is to adopt the convention to prepend '_' to your arguments (if you like cleaner member variable declarations). Like so,

class Foo {
public:
    Foo(int _x) : x(_x), y(0) {}
    Foo(int _x,int_y) { x=_x; y=_y; }
private:
    int x, y;
};

Using this is also effective.

ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42