Why do I need the this pointer in C++?

  • Thread starter yungman
  • Start date
In summary, the "this" pointer in C++ allows objects to access their own data members and functions, as well as share the same set of member functions between all instances of a class. It is often used in operator overloading for convenience and "elegance", but should be used judiciously to avoid making code difficult to understand and maintain.
  • #1
yungman
5,718
241
I have been reading this pointer. I read this article: https://www.geeksforgeeks.org/this-pointer-in-c/
" Meaning each object gets its own copy of data members and all objects share a single copy of member functions. "

Is this true? I just want to make sure that there is really only ONE COPY of the member functions in the memory for each class and ALL objects share the same set of functions.

Also another article https://docs.microsoft.com/en-us/cpp/cpp/this-pointer?view=msvc-160
claims "{month = mn; this->month = mn; (*this).month = mn;} // These three statements are equivalent". why do I need the "this" pointer? It's almost like putting "this" just to make it more confuse! Just use month = mn.

Seems like a lot of the stuffs in operator overloading are more for "elegance" than really necessary. You can easily write a few more lines instead of using all these "elegant" code just to save a few lines. Problem is people are using this, you won't be able to follow their codes without understand it.

Thanks
 
Technology news on Phys.org
  • #2
yungman said:
Also another article https://docs.microsoft.com/en-us/cpp/cpp/this-pointer?view=msvc-160
claims "{month = mn; this->month = mn; (*this).month = mn;} // These three statements are equivalent". why do I need the "this" pointer? It's almost like putting "this" just to make it more confuse! Just use month = mn.
Suppose you are calling a function that expects a pointer (perhaps to an entire structure of your data). Then you have your "this" pointer to give it.
Seems like a lot of the stuffs in operator overloading are more for "elegance" than really necessary. You can easily write a few more lines instead of using all these "elegant" code just to save a few lines. Problem is people are using this, you won't be able to follow their codes without understand it.
Like many things, operator overloading should be used judiciously. If you are going to do a lot of work with vectors, or matrices, or strings, or databases, then it might be handy for A+B to represent the appropriate "addition" (vector addition, matrix addition, string concatenation, adding a record to a database, etc.). If you use that overload enough, what seems just to be "elegance" can make all the difference.
On the other hand, I have seen programmers who seem to think that every simple program they write would benefit from them developing their own language through overloading all the operators. It can make the program MUCH harder for another person to understand and maintain.
 
  • Like
Likes yungman
  • #3
yungman said:
I have been reading this pointer. I read this article: https://www.geeksforgeeks.org/this-pointer-in-c/
" Meaning each object gets its own copy of data members and all objects share a single copy of member functions. "

Is this true? I just want to make sure that there is really only ONE COPY of the member functions in the memory for each class and ALL objects share the same set of functions.
Yes, all instances of a class (objects) share the same set of member functions, but each class instance has its own data members.
yungman said:
Also another article https://docs.microsoft.com/en-us/cpp/cpp/this-pointer?view=msvc-160
claims "{month = mn; this->month = mn; (*this).month = mn;} // These three statements are equivalent". why do I need the "this" pointer? It's almost like putting "this" just to make it more confuse! Just use month = mn.
Consider this example of a class that represents a 3-D vector.
Snippet from the header:
C++:
class Vec3D
{
private:
    double x;
    double y;
    double z;
public:  
    Vec3D(double x = 0, double y = 0, double z = 0);
    Vec3D operator=(const Vec3D& v);
    <other declarations>
};
From the implementation file, the implementation of the overloaded assignment operator:
C++:
Vec3D Vec3D::operator=(const Vec3D& v)
{
    this->x = v.x;
    this->y = v.y;
    this->z = v.z;

    return *this;  
}
The overloaded assignment operator would be used like this:
C++:
    Vec3D v1(2.0, 3.0, 4.0);
    Vec3D v2;     // Construct a vector using default values
    v2 = v1;      // Assign the values in v1 to those in v2
The first line above uses the constructor to create v1, setting its x, y, and z data members to 2.0, 3.0, and 4.0 respectively.
The second line creates v2, using the default values of 0.0, 0.0, and 0.0.
The third line assigns the values in v1 to those in v2, using the overloaded assignment operator.

Question for you: Looking at the code for operator= (overloaded assignment operator),
1) it has to return a Vec3D object.
2) how would you do that without having a this pointer?
yungman said:
Seems like a lot of the stuffs in operator overloading are more for "elegance" than really necessary.
Some are, but as I mentioned before, it is often helpful to provide a way to output the values in a class using the << stream insertion operator. It's also helpful to provide a way to assign the values in one object to another using the assignment operator. Other possibilities are to overload + to concatenate strings, which is something that is done in the string class.
 
Last edited:
  • Like
Likes sysprog and Vanadium 50
  • #4
FactChecker said:
Suppose you are calling a function that expects a pointer (perhaps to an entire structure of your data). Then you have your "this" pointer to give it.Like many things, operator overloading should be used judiciously. If you are going to do a lot of work with vectors, or matrices, or strings, or databases, then it might be handy for A+B to represent the appropriate "addition" (vector addition, matrix addition, string concatenation, adding a record to a database, etc.). If you use that overload enough, what seems just to be "elegance" can make all the difference.
On the other hand, I have seen programmers who seem to think that every simple program they write would benefit from them developing their own language through overloading all the operators. It can make the program MUCH harder for another person to understand and maintain.
Thanks for the reply. Maybe that's the reason Gaddis book only talk about "return *this;" for returning the pointer to the object. The book does not go into "{month = mn; this->month = mn; (*this).month = mn;} ". I can see return the pointer of the object is definitely useful.

Can you give me a hint which part of the overloading is more useful and what I don't have to go that deep? I am going to study all of them, but I will put more time to work out problems on the part that is more important. Like you said, it's not about using them, it's about being able to understand what other people wrote. I remember I read "this->" many times before this, so it's important to understand even if I choose not to use it.

So far, operator=() seems to be useful as you can copy objects. I have not study through operator+() yet, but seems like in order to use it, all the variables in the objects has to be numbers. If you have c-string like people's name or something, you really cannot do operator+().

Thanks
 
  • #5
Imagine implementing the COMPLEX data type in a language that doesn't already have it. As a minimum, you would want all the same operators as you have for int or float.
 
  • Like
Likes sysprog, Vanadium 50 and FactChecker
  • #6
yungman said:
Can you give me a hint which part of the overloading is more useful and what I don't have to go that deep?
The concept of overloading is very useful and general. You can overload functions and operators. There are not some that are more important than others. If there is a function or operation that is going to be used a lot for particular objects, overloading is a nice shorthand.
So far, operator=() seems to be useful as you can copy objects. I have not study through operator+() yet,
They are all the same concept. You can define a function that is represented by the '+' operation.
but seems like in order to use it, all the variables in the objects has to be numbers. If you have c-string like people's name or something, you really cannot do operator+().
No. That is wrong. The operation that the overloaded '+' does is not required to have any similarity to the operation of numerical addition. In fact, you could overload the '+' operation to a function that involves complicated things like putting data into a file. Or it could rotate a visual scene clockwise by a certain number of degrees. It all depends on what is needed and beneficial for a particular subject matter and class. The '+' is just a symbol that can be used to represent a function as you desire. Of course, it is nice for it to represent something that can intuitively be thought of as an addition in the context of that class.
 
Last edited:
  • Like
Likes yungman
  • #7
Thanks guys, I guess I will spend more time going through them and work out the programs.
 
  • #8
I have question about the syntax. I notice in different situation, the syntax is a little different, but I have not been able to find explanation of the different syntax.

For normal basic operator overloading, the syntax is like the following, this is a function where it will take the member variables and copy into the right object. Then it copies into the member variables of the left object.
C++:
//In main()
PersonInfo person1, person2;
person2 = person1;
C++:
//In PersonInfo.h
void operator=(const PersonInfo &right){...}
BUT, in this pointer that has return *this, for a= b = c. The syntax is like this in header file
C++:
//In PersonInfo.h:
const PersonInfo operator=(const PersonInfo& right)
C++:
//In main():
PersonInfo a, b, c;
a = b = c;
what is PersonInfo in front of the operator=() means in this PersonInfo operator=()?

Then this is in the Implementation file for class FeetInches. In normal declaration, it's just
C++:
FeetInches::operator+(const FeetInches &right)
But in this, it has extra FeetInches before that. What does that mean?
C++:
FeetInches FeetInches::operator+(const FeetInches &right)
I understand I just need to follow the syntax, BUT I really want to understand what is the meaning of the syntax. Like func(&var) means it pass the var by reference, I want to understand what those syntax means.

Thanks
 
  • #9
I think I got it, it's just like int func() that return an integer. PersonInfo operator+(PersonInfo &right) returns the pointer to a class object. It's just that simple.

I the Implementation file, the idea is the same, you can have void FeetInches:: operator+() that return nothing, OR you have FeetInches FeetInches:: operator+() that return a pointer of a class object.
Am I correct?
 
Last edited by a moderator:
  • #10
yungman said:
I think I got it, it's just like int func() that return an integer. PersonInfo operator+(PersonInfo &right) returns the pointer to a class object. It's just that simple.
Almost. Your example declaration returns a PersonInfo object, not a pointer to one.
It's the difference between this declaration: int Func() and this one: int* Func(). The first version returns an int; the second returns a pointer to an int.
yungman said:
I the Implementation file, the idea is the same, you can have void FeetInches:: operator+() that return nothing, OR you have FeetInches FeetInches:: operator+() that return a pointer of a class object.
Am I correct?
Again, almost. This example declaration returns a FeetInches object, not a pointer to one.
 
  • Like
Likes yungman
  • #11
Mark44 said:
Almost. Your example declaration returns a PersonInfo object, not a pointer to one.
It's the difference between this declaration: int Func() and this one: int* Func(). The first version returns an int; the second returns a pointer to an int.
Again, almost. This example declaration returns a FeetInches object, not a pointer to one.
Thanks Mark
It is my bad. The reason I said it's pointer to the object is because in the declaration, it said return *this as shown:
C++:
    const PersonInfo operator=(const PersonInfo& right)    // Overloaded = operator
    {   delete[] name; name = new char[strlen(right.name) + 1];
        strncpy_s(name, strlen(right.name) + 1, right.name, strlen(right.name) + 1); 
        age = right.age;  return *this;
    }
Yes, if it is not for that, it is returning the object.
I have more questions, I post in another post.

Thanks for your help.
 
  • #12
I have question about this pointer, this is the program I am experimenting with:
C++:
#include <iostream>
using namespace std;
class Test
{ public:
    int x; int y;
    Test(int x = 0, int y = 0)
    { (*this).x = x; this->y = y; }//this->x=x same as (*this).x=x.
    Test& setX(int a) { x = a; return *this; }
    void pthis() { cout << " this = " << this <<  "\n\n"; }//They are the same.
    void py() { cout << " y = " << y << "\n\n"; }
    Test& setY(int b) { y = b; return *this; }
    void print() { cout << " x = " << x << "\ty = " << y << "\n\n"; }
};
int main()
{    Test obj1(5, 5);
    obj1.setX(10).setY(20);
    obj1.print();
    obj1.pthis();
    cout << " &obj1 = " << &obj1  << " same as this.\n\n";
    //cout << (*this).x();
    return 0;
}
1) What is this->y = y for? Why put it there?
2) Notice I can print out this in line9, BUT I cannot do it in line20 in main. I already put int x in public, there is no conflict.

I know this is a pointer to the object like obj1 in this case. But I still not quite understand what the others are for like using in this->x=x. I've seen this in other programs in the pass, must be quite common, so I better understand it good.

Thanks
 
  • #13
Would you please make it easy for people to help you by using proper bracketing and indentation?
 
  • Sad
Likes yungman
  • #14
yungman said:
it said return *this as shown:
Which means it's going to return what this is pointing to -- an object.
 
  • #15
Mark44 said:
Which means it's going to return what this is pointing to -- an object.
Yes, in my case, it's pointing to obj1. I actually display the address and &obj1 = this.

Thanks
 
  • #16
I presume by your "Sad" comment you mean "No, I shall not make it easy for people to help me by using proper bracketing and indentation."

Your choice.
 
  • #17
Vanadium 50 said:
I presume by your "Sad" comment you mean "No, I shall not make it easy for people to help me by using proper bracketing and indentation."

Your choice.
No it's sad you don 't have better things to do.

People are coming, Happy ThanksGiving.
 
  • Sad
Likes jbriggs444
  • #18
A couple comments on the code in post 12.

  • pthis() -- line 9 -- is a terrible name for a function. The p prefix suggests that the function will return a pointer to this, but this is already a pointer. In fact, the function is written to return this.
  • py() -- line 10 -- is also a terrible name, again suggesting that it will return a pointer, this time to the y data member. This function actually doesn't return anything it all.
You really should make more of an effort at coming up with better, more meaningful names for variables. The name you give some variable or function plays a big role in how you think about that thing. Giving it a name that is unhelpful can keep you from understanding what it is supposed to be when you look at your code a few weeks or months later.
yungman said:
1) What is this->y = y for? Why put it there?
The code is in the Test constructor, which is supposed to construct a Test object with both data members set to certain values. If the constructor is called with no arguments, x and y will be set to 0. If the constructor is called like this, Test(3, 5), x and y will be set with those values.
Similar to what you note in your comment, this->y = y is just alternate notation for (*this).y = y .
yungman said:
2) Notice I can print out this in line9, BUT I cannot do it in line20 in main. I already put int x in public, there is no conflict.
If you're referring to this line, which you commented out --
C++:
//cout << (*this).x();
Line 9 prints the address that this represents. In line 20, you're attempting to print the value of x, not this. x is a data member, not a function, so the parentheses should not be used.
 
Last edited:
  • Like
Likes Vanadium 50 and yungman
  • #19
yungman said:
No it's sad you don 't have better things to do.

Than to help you get the help you want?

You are making mistakes. Lots of them. People are telling you how to fix them and how not to make them in the future. You really should listen to them.

In the case in question, if you untangled the rats' nest of code into something properly bracketed, indented and with non-terrible variable names, more people could help you and could help you faster. You might even be able to solve it yourself.
 
  • #20
Mark44 said:
A couple comments on the code in post 12.

  • pthis() -- line 9 -- is a terrible name for a function. The p prefix suggests that the function will return a pointer to this, but this is already a pointer. In fact, the function is written to return this.
  • py() -- line 10 -- is also a terrible name, again suggesting that it will return a pointer, this time to the y data member. This function actually doesn't return anything it all.
You really should make more of an effort at coming up with better, more meaningful names for variables. The name you give some variable or function plays a big role in how you think about that thing. Giving it a name that is unhelpful can keep you from understanding what it is supposed to be when you look at your code a few weeks or months later.
The code is in the Test constructor, which is supposed to construct a Test object with both data members set to certain values. If the constructor is called with no arguments, x and y will be set to 0. If the constructor is called like this, Test(3, 5), x and y will be set with those values.
Similar to what you note in your comment, this->y = y is just alternate notation for (*this).y = y .

If you're referring to this line, which you commented out --
C++:
//cout << (*this).x();
Line 9 prints the address that this represents. In line 20, you're attempting to print the value of x, not this. x is a data member, not a function, so the parentheses should not be used.
Thanks Mark

I had so much problem making sense of the this pointer, I read through a lot of the articles and still don't get it. Finally I started watching youtube video. This is the one I watched and lone and behold, I think I understand it.


But I want to verify: I have been really over complicated the whole thing, The this point is really a built-in pointer that we need to be aware of it and not really using it most of the time with a few exceptions like return *this to return the address of the calling object.

This is the program in the video, I typed it in and step by step following the video. the program is super easy, it just show HOW the compiler interpreted the program when an object of a class calling the member functions. The compiler just adds in the this-> and all the stuffs I put into //commenting. it's like when compiler sees:
int get(){return x;}, it reads like int get(Base* const this) {return this->x;} inside the compiler. All it is is just a way to keep track of which object is calling and make sure only the member variable of that object is being used.

Here is the program with the comment lines:
C++:
#include <iostream>
using namespace std;
class Base
{ int x;
public:
    Base() {}
    Base(int a) :x(a) {  }
    int get(){return x;}
//compiler changes to:    int get(Base* const this) {return this->x;} when b2 calls.

    void set(int a){x=a;}
//compiler changes to:    void set(Base* const this,int a){this->x=a;} when b2 calls.
};
int main()
{
    Base b1;
    Base b2(10);
    b2.get();//compiler changes to:     Base::get(&b2);
    b2.set(20);//compiler change to:    Base::set(&b2,20);
    return 0;
}

Man! Did I sweat this out the last two days!...Almost for nothing! Most are just how the compiler interpret the program, not that we have to write like that.

Thanks
 
Last edited:
  • #21
Why the following two lines of code in header file works the same? One has & after the Length to signal returning a pointer of the object.

C++:
Length& operator+(const Length&right) { Length temp; temp.Len = Len + right.Len; return temp; }
Works the same as
C++:
Length operator+(const Length&right) { Length temp; temp.Len = Len + right.Len; return temp; }

I ran both in the program, they gave the same result.
Thanks
 
  • #22
yungman said:
One has & after the Length to signal returning a pointer of the object.
Actually, it's a reference, not a pointer. If it were a pointer, it would be Length*. Nevertheless, I think the effect would be similar in both cases, as far as your question is concerned.

How do you know the first one "works"? Could you have just been lucky? :wink:

The first version returns a reference to a local variable (a variable that is declared inside operator+()). What happens to local variables after operator+() finishes and you return to main(), or to whatever function called operator+()?
 
Last edited:
  • Like
Likes yungman
  • #23
Thanks Jtbell
This is the program I am experimenting with. It's in line5 that I can remove the '&' and the result is the same. Yes, I should say reference.
C++:
#include <iostream>
using namespace std;
class Length
{public: int Len;
         Length& operator+(const Length&right)
            { Length temp;  temp.Len = Len + right.Len;    return temp; }
         Length operator-(const Length&right)
            { Length temp;  temp.Len = Len - right.Len;    return temp; }
};
int main()
{    Length L1, L2, L3;
    cout << " Enter first  number: "; cin >> L1.Len;
    cout << " Enter second number: "; cin >> L2.Len; cout << endl;
    L3.Len = L1.Len + L2.Len;
    cout << " first number + second number = " << (L1.Len + L2.Len) << "\n\n";
    L3.Len = L1.Len - L2.Len;
    cout << " first number - second number = " << (L3.Len) << "\n\n";
    //L3 = L1.operator+(L2);//Still use the operator function
    cout << " Using L3 = L1.operator+(L2), L3.Len = " << (L1.operator+(L2)).Len << "\n\n";

Thanks
 
  • #24
I am surprised it compiles without at least a warning. Something like "reference to local variable ‘temp’ returned"

I am also surprised it runs without crashing or an error.

What is the purpose of the & after Length? Why do you want it?
 
  • #25
The way you normally use an operator+() function is to write something like L3 = L1 + L2. Is that in the part of the program that appears to be missing at the end?
 
  • #26
Vanadium 50 said:
I am surprised it compiles without at least a warning. Something like "reference to local variable ‘temp’ returned"
In VS, which yungman also is using: " warning C4172: returning address of local variable or temporary: temp"
The program as written is pretty trivial, and doesn't show off the usefulness of overloaded operators. The Length class is just a fancy wrapper for an int value. A more interesting class in which to override the + operator might be a class of complex numbers, with overridden operators for +, -, *, and /.
 
  • #27
Mark44 said:
In VS, which yungman also is using: " warning C4172: returning address of local variable or temporary: temp"

On the one hand, I'm happy the compiler thows a warning. On the other, it would be nicer if someone asking for help to point out where the compiler complains.

Mark44 said:
The program as written is pretty trivial, and doesn't show off the usefulness of overloaded operators.

I agree.

Mark44 said:
The Length class is just a fancy wrapper for an int value.

I agree.

Mark44 said:
A more interesting class in which to override the + operator might be a class of complex numbers, with overridden operators for +, -, *, and /.

I agree. However it does require some thinking about type conversion and how the programmer wants it to work. Is (1+i)(1-i) equal to 2 + 0i? Or 2?
 
  • #28
Vanadium 50 said:
I am surprised it compiles without at least a warning. Something like "reference to local variable ‘temp’ returned"

I am also surprised it runs without crashing or an error.

What is the purpose of the & after Length? Why do you want it?
I saw in another article before where one constructor is Buf operator+() and another Buf& operator+() with different arguments. So I added the & just for the hell of it and see what happens!

This is the link where Buf& operator=(), (I figure = and + both use operator function).
https://docs.microsoft.com/en-us/cpp/cpp/this-pointer?view=msvc-160
 
Last edited:
  • #29
jtbell said:
The way you normally use an operator+() function is to write something like L3 = L1 + L2. Is that in the part of the program that appears to be missing at the end?
No, I actually did that, but both the Gaddis book and some video said L3 = L1 + L2 can be written as
L3 = L1.operator+(L2). So I want to verify by putting in the program. It works! I always try things like this, I don't take their words. I learn things sometimes when I keep trying things like this. I learn better never believe anything I read even from the book. Trust but verify. Seen too many mistakes in textbooks, even the famous ones.

But this has nothing to do with &, that's totally different subjects.
 
  • #30
FactChecker said:
Suppose you are calling a function that expects a pointer (perhaps to an entire structure of your data). Then you have your "this" pointer to give it.Like many things, operator overloading should be used judiciously. If you are going to do a lot of work with vectors, or matrices, or strings, or databases, then it might be handy for A+B to represent the appropriate "addition" (vector addition, matrix addition, string concatenation, adding a record to a database, etc.). If you use that overload enough, what seems just to be "elegance" can make all the difference.
On the other hand, I have seen programmers who seem to think that every simple program they write would benefit from them developing their own language through overloading all the operators. It can make the program MUCH harder for another person to understand and maintain.
I got it, This is because in the function, one has to define what to do like adding certain variable from left object to temporary object and return the object. One can simply skip the c-string member data and only perform math operation on the member data that are numbers.

These are all new to me, takes a little time to twist my mind to think like that.

Thanks
 
  • #31
Vanadium 50 said:
What is the purpose of the & after Length? Why do you want it?
There IS a purpose to returning the LHS as a reference in assignment operator overloads (like +=), but not simple binary operators like +.

How do I know this? Because I looked it up. I have been programming (not in C++ obviously) for over 40 years without the benefit of this knowledge, and I do not expect ever to need it again.

Why someone would spend time learning about operator overloading (or teaching it for that matter) in a first introduction to C++ is beyond me.
 
  • #32
pbuk said:
There IS a purpose to returning the LHS as a reference in assignment operator overloads (like +=), but not simple binary operators like +.

Oh, I am sure there is a purpose. There is a purpose to almost everything in C++, except maybe goto. :wink:

pbuk said:
How do I know this? Because I looked it up.

Well that's just crazy talk.o0)

Anyway, I was obviously unclear. My question was less "what is this structure used for?" and more "what are you trying to accomplish with this code?" The answer is

yungman said:
So I added the & just for the hell of it and see what happens!

Followed by sending us to figure out what was going without telling us the compiler threw a warning, and making the incredible claim that it worked anyway. I mean, it could have worked, in the sense that jumping to a random spot in memory could work, but it's incredibly unlikely.

pbuk said:
Why someone would spend time learning about operator overloading (or teaching it for that matter) in a first introduction to C++ is beyond me.

I agree. To be fair to Mr. Gaddis, it's only three paragraphs in the entire book.
 
  • #33
pbuk said:
Why someone would spend time learning about operator overloading (or teaching it for that matter) in a first introduction to C++ is beyond me.
I think that it is too commonly used to be skipped. I tend to think that it is overused, but even with reduced, judicious use, it would appear a lot.
 
  • #34
FactChecker said:
I think that it is too commonly used to be skipped. I tend to think that it is overused

I agree. I also don't think Gaddis does a very good job here - he does not emphasize the most used (and IMHO best) use case: comparison operators. Is "van der Meer" before or after "Van Cleef"?
 
  • #35
Mark44 said:
warning C4172: returning address of local variable or temporary: temp

Doing this in very simple cases will work as expected. This leads one to think that what they are doing is safe. Which leads to nearly impossible to debug code.

BoB
 

Similar threads

  • Programming and Computer Science
Replies
5
Views
878
  • Programming and Computer Science
Replies
19
Views
2K
  • Programming and Computer Science
Replies
2
Views
930
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
Replies
5
Views
811
  • Programming and Computer Science
Replies
18
Views
2K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
2
Views
764
  • Programming and Computer Science
Replies
2
Views
362
  • Programming and Computer Science
Replies
18
Views
1K
Back
Top