Sign in to follow this  

Good form using "this" pointer?

This topic is 392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone,

 

Not an altogether important question but one I have been wandering about for some time. Say we have the following example.

Point(int x, int y){
   this->x=x;
   this->y=y;
}

I don't see this very often, and I have heard, and read some snarky remarks with respect to the above code. Just wandering if there are any problems which I don't understand.

 

Bad form/style by 2016 standards?

Performance hit?

Too verbose?

 

Thanks,

 

Mike

Share this post


Link to post
Share on other sites

This all overthinking really, but I'd prefer you rename either the incoming x and y, or the members, and get in the habit of using an initializer list.  For this simplistic example, it doesn't really matter though.

Share this post


Link to post
Share on other sites

Hello everyone,
 
Not an altogether important question but one I have been wandering about for some time. Say we have the following example.

Point(int x, int y){
   this->x=x;
   this->y=y;
}
I don't see this very often, and I have heard, and read some snarky remarks with respect to the above code. Just wandering if there are any problems which I don't understand.
 
Bad form/style by 2016 standards?
Performance hit?
Too verbose?
 
Thanks,
 
Mike


If that's a constructor, I would normally write it like this:
Point(int x, int y) : x(x), y(y) {
}
I don't think there is anything wrong with this type of code.


EDIT: Oh, boy. Ninja'd by a half hour. I didn't see dmatter's post. My bad. Edited by Álvaro

Share this post


Link to post
Share on other sites
My personal take is that I _want_ it to be good form and that I find the automatic class scope lookup rules in C++ to be a mistake, but the reality is that those rules do exist and that using this-> unnecessarily is uncommon.

Coding that way won't hurt anything but it will make the code look a little alien or weird to a majority of C++ programmers, and getting in the habit of writing code _for other people_ is a good thing.

Share this post


Link to post
Share on other sites

In my experience, it's much more common to use a prefix such as m_ instead of this-> to disambiguate member variables.
I personally hate the this-> style for being too verbose... however, accessing a member variable is a performance concern when doing low level programming, and the this-> style makes this fact painfully obvious to the eye and impossible to miss, which could help you spot potential performance problems (e.g. type aliasing causing excessive loads) so that could be a positive for it. If you're not writing the kind of code where you care about whether type aliasing rules are going to cause an excessive load instruction to be generated though, then that positive isn't really applicable to you though.

Share this post


Link to post
Share on other sites

My personal take is that I _want_ it to be good form and that I find the automatic class scope lookup rules in C++ to be a mistake, but the reality is that those rules do exist and that using this-> unnecessarily is uncommon.

Coding that way won't hurt anything but it will make the code look a little alien or weird to a majority of C++ programmers, and getting in the habit of writing code _for other people_ is a good thing.

Well, you could always use something like Resharper or lint (is that still around?) to enforce that idiom?

Share this post


Link to post
Share on other sites

Thanks for all the great reply guys.

 

I just want to make it clear that I don't use the above code snippet, as I rarely see anything of the sort when looking at other people's source code. But once in a while I do come upon it and I was just curious that's all. The initilizer list is my preference.

 

I also know that many people here work/worked for professional software companies, so I wanted to know some common practices.

 

Thanks again,

 

Mike

Share this post


Link to post
Share on other sites

I just want to make it clear that I don't use the above code snippet, as I rarely see anything of the sort when looking at other people's source code. But once in a while I do come upon it and I was just curious that's all. The initilizer list is my preference.

 

In C++, it may have been okay, but as you start learning languages with dynamic typing, it actually becomes preferable to explicitly use the 'this' (or 'self') keyword.  In Python, the 'self' keyword becomes mandatory to indicate that you are referencing the instance variable, rather than creating a new local variable.

Share this post


Link to post
Share on other sites

m_ is the only prefix I can think of off the top of my head that I still really use, in C++ I just find it much more convenient than throwing a bunch of this-> everywhere.

 

For performance it's negligible to say the least. But really I've found performance to be a dirty word most of the time, 95% of performance loss usually happens in code that you know is doing a lot of something, other things would be obvious in profiling. Write it however makes it easiest to work with.

Share this post


Link to post
Share on other sites

All answers are correct. But nobody told you the coding convention way. The m_ prefix is more than 20 years old and your code becomes readable for cyborgs not for humans.

I hardly advice any C++ coder to take a look at the XNA Game Library how objective code can and should be done. You can easily take over the .NET/C# naming conventions, they play along C/C++ quite nice.

What to do?

 

Private members are written with underscore in camel case (_backDoor) and public members and all functions are written in pascal case (BackDoor).

Function parameters are written in camel case (backDoor).

 

So you would have:

private int _x, _y; // internal class parameters or like proposed m_x, m_y

and then:

 

function DoSomething(int x, int y)

{

_x = x;

_y= y;

}

 

The m_ prefix is more than 20 years old. Also the prefixes like p for pointer or lp, or sz, or lpsz are an overkill.

If you go into such detail, you should be aware that your code is not intuitive.

Share this post


Link to post
Share on other sites

My personal take is that I _want_ it to be good form and that I find the automatic class scope lookup rules in C++ to be a mistake, but the reality is that those rules do exist and that using this-> unnecessarily is uncommon.

Coding that way won't hurt anything but it will make the code look a little alien or weird to a majority of C++ programmers, and getting in the habit of writing code _for other people_ is a good thing.

 

I 100% agree. I have come to love Python and Rust's explicit self.

 

Also, using this-> explicitly instead of (god forbid) prefixes such as m_, has massive advantages if you ever have to transform your code from explicit types to a hierarchy of templates (and need to support GCC or clang which don't violate pretty much all name lookup rules like VS does...)

 

Example:

template <typename Policy>
struct Foo : private Policy
{
	int foo() { return m_foo; }
};

struct AnswerPolicy
{
	int m_foo = 42;
};

int main(int, char**)
{
	return Foo<AnswerPolicy>().foo();
}

Produces the following error:

this.cpp: In member function 'int Foo<Policy>::foo()':
this.cpp:4:21: error: 'm_foo' was not declared in this scope
  int foo() { return m_foo; }
                     ^~~~~

This ( :wink: ), however, is correct:

template <typename Policy>
struct Foo : private Policy
{
	int foo() { return this->fooValue; }
};

struct AnswerPolicy
{
	int fooValue = 42;
};

int main(int, char**)
{
	return Foo<AnswerPolicy>().foo();
}

Edited by l0calh05t

Share this post


Link to post
Share on other sites

The initilizer list is my preference.

 

Ah, you didn't make it explicit in the original post that you were asking specifically about using this in the constructor to disambiguate member variables from same-named arguments - as opposed to the general case of using a this-> prefix throughout the code to make it explicit which variables are members and which are just locals.

 

The initialiser list should be preferred in general, but that's a separate issue to how variable names are chosen - personally I have no strong opinions on the matter and have seen 'm_' prefixes for members, underscore suffixes for members, underscore suffixes for constructor arguments, slightly contrived name variations for arguments, etc. It's not a big deal.

Share this post


Link to post
Share on other sites

I'd say the most important thing is to pick a convention and stick with it throughout your code. Using a prefix for all members (m_ or just _) or just this./this-> when there's a conflict is fine, as long as you are consistent.

 

In my projects, I try to avoid conflicts to begin with, and when I get them anyway (mostly in constructors) I go with this.whatever (I work in C#).

Share this post


Link to post
Share on other sites

Using a prefix for all members (m_ or just _) or just this./this-> 

 

'this.'? Do some compilers support 'this' as a reference or something?

 

I use this-> consistently, but am leaning away from it and intend to review my entire coding guidelines in a few years once my current (multi-project) project is finished. I'll probably switch to mVarName.

Share this post


Link to post
Share on other sites

 

Using a prefix for all members (m_ or just _) or just this./this-> 

 

'this.'? Do some compilers support 'this' as a reference or something?

 

 

Kylotan is right, I work mostly in C#, so that's where I use "this.", sorry for the confusion. My intention was to say that I prefer the "this"-syntax of whatever language I'm using

Share this post


Link to post
Share on other sites

I think the best advice in this thread is to avoid cases where you have the same symbol (x and y, in the original example) referring to multiple things in the same scope. You can work around it, and get away with it for a time, but if the code lives long enough, it will end in tears.

 

Given that, I find the this-> syntax somewhat distasteful (talking C++, here. Maybe it makes more sense in C# or something, I don't know). At best it is redundant (member variables are in scope in member functions), at worst it is working around the multiple symbol issue above. I would stay away from it.

 

I generally use m_, but that is just because I'm in the habit from the company I worked at for years. I could easily be talked out of it on a new project.

 

Good luck!

Geoff

Share this post


Link to post
Share on other sites

Given that, I find the this-> syntax somewhat distasteful (talking C++, here. Maybe it makes more sense in C# or something, I don't know).
 

 

I was going to say that it's the same in C#, but I may have changed my mind. I think that C# is much more likely to be used with competent tools than C++, where name conflicts are almost guaranteed to stand out due to highlighting etc. C++ is more likely to be read with a simpler/dumber editor, partially due to the nature of the language and compilation model, that relying on naming is more important/encouraged in that case.

Share this post


Link to post
Share on other sites

Years ago it would be a good practice.

These days naming conventions overcame these practices. 
So if you name your variables right (x becomes mX or _x) you don't need to use the "this" keyword.

Point(int x,int y) {

    _x=x;

    _y=y;

}

 

I don't know of any optimization of performance because of it. I've read long ago it actually makes the compilers life easier because it knows what kind of variable you are refering to. But I think it's just either in compilation time or completly unrelevant today. 

Share this post


Link to post
Share on other sites

These days naming conventions overcame these practices.

I'd almost say the opposite has happened.

5 years ago, most codebases had settled on member variable prefixing schemes to avoid this, but increasingly I get the "we don't use prefixing, because we all use IDEs" argument (particularly in Java and C£).

Share this post


Link to post
Share on other sites

This topic is 392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this