dereferencing pointers using "this" - c++

I am trying to call a variable in my class using the this keyword in two ways but I am confused with the 2nd way. The correct way of dereferencing happens to be "(*this).num" however, I was wondering why "*(this).num" is not right as well. The error I get with *(this).num is
request for member 'num' in 'this', which is of pointer type çlass const'*
class::class(int n): num(n)
{
cout << "num= " << num << endl;
cout << "this->num" << this->num << endl;
cout << "(*this).num" << (*this).num << endl;
}
Because if you define
int i = 9;
int *ptr = &i;
cout<<*(ptr)<<endl;
and call *(ptr) it works. But why doesn't it work in my class?

It's simply a matter of operator precedence. The binary dot operator has a higher precedence than the unary star operator, so *(this).num (the parentheses have no effect there) is interpreted as *(this.num), and not as (*this).num. The compiler is telling you that, because this is a pointer, this.num doesn't make sense: you can't apply the dot operator directly to a pointer.

You are using two operators: the indirection/dereferincing operator * and the member access operator ..
If you have a look at the precedence of these operators, you'll see that . has higher precedence than * (that is, . will be applied before *), so thus *(this).num is basically the same as writing *(this.num).
Since this is a pointer, you can't use the . operator on it, which is also what the error message is telling you (try using -> instead).
The reason why your second example works, is that you're not using the . operator, and thus there is no precedence to be messed up.

. has higher precedence than *.
So writing *(this).num is equivalent to (*((this).num))). Or *(this.num).
Your second example is completely different from the first since there is no access to members . or ->.
If you don't know all the precedences, or even if you do, it's usually more readable to add the appropriate brackets.

One works and the other doesn't because they are not the same thing!
*(ptr) and *(this) are the same, but *(this).num and (*this).num are not the same, that's the whole point of adding the parentheses! They change how the sub-expressions are grouped, just like in mathematics.
The parentheses in (ptr) and (this) are completely redundant, you are grouping a single sub-expression, which does nothing. In (*this) it's not redundant, it ensures that you dereference the pointer, so in (*this).num it dereferences the pointer first and then the member access .num is applied to the result of that dereference.
Compare it to mathematics:
(1) is just 1, and similarly (ptr) is just ptr
-(1) is just -1, and similarly *(ptr) is just *ptr
But -(1 + 3) and -(1) + 3 are completely different, because you change the order of the operators.
Similarly, *(this.num) and (*this).num are completely different.

The short answer is syntax.
(ptr) looks like this: evaluate expr inside () first, then dereference the result which is in this case is int. It's fine, the same as *ptr.
*(this).num is eq. with *this.num which means get the num member of this. After that dereference num. It's incorrect as you can see because "this" is a pointer to the current object.
(*this).num means dereference this, then get the num member.

Related

Why won't [ ] brackets work when dereferencing a pointer?

If I have a std::vector, I can access a member because the square bracket operator is overloaded in the vector class. If I have a pointer to a vector, I can dereference the pointer and use this operator. But with the arrow -> operator it won't let me use it. Example:
// Excuse the UB here, it's just for illustration
std::vector<int> myVector;
std::vector<int>* pToVector;
myVector[4] = 0; // Works fine
(*pToVector)[4] = 0; // Works fine
pToVector->[4] = 0; // Doesn't work
(pToVector->)[4] = 0; // Doesn't work
Seeing as though the -> arrow operator dereferences the pointer, is there a reason not to expect that this would work? Or is it just one of those things about the language?
Thanks.
std::vector<int> myVector;
std::vector<int>* pToVector;
myVector[4] = 0; // Works fine.
(*pToVector)[4] = 0; // Works fine
pToVector->[4] = 0; // Doesn't work
(pToVector->)[4] = 0; // Doesn't work
If you must use a pointer to an object to access an overloaded operator of the object's class, you will have to call it explicitly.
pToVector->operator[](4)
... By the way, Accessing an index outside myVector.size() is Undefined Behavior. This includes the statements with the comment annotation in your code about // Works fine.
The correct syntax for the second two lines would be:
(*pToVector)[4] = 0;
//dereference the pointer and then call operator[] on the object returned by the dereference
You could use the -> operator to access regular member functions like this:
pToVector->size();
Technically you could try yo call the operator[] by name but it is more verbose.
The reason is that [] is an operator, and the short operator syntax does not require or allow member access operators. This applies to both member access operators . and ->, which makes sense because the latter is just shorthand for (*a).b.
E.g. all disallowed a. & b, a->^b
Technically, it also applies to the rarer .* and ->*. Note that the latter is not -> followed by operator*, but a pointer to member pointer dereference.
-> operator is replacement for dot operator, except it dereferences a pointer first. It is used to access attributes(members and functions). For your operation, operator[] is the attribute. So, pToVector->operator[](4) is applied to (*pToVector)[4] = 0
The -> operator does not just dereference, it also accesses a member. You are accessing an element*, not a member. -> could have been defined to allow that, but wasn't.
* To be more precise, a vector is letting you access an object as if it were an element of an array, but it doesn't change the syntax.
I think the square brackets dereference the pointer, so you ended up dereferencing twice there.
ptoVector[4] I think would have worked and been sufficient since the square brackets do a dereference for you.

Incrementing pointer not working

I’m trying to increment pointer. I was sure that it is similar to do i+=1 , but I’m getting adress.
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i = 42;
int *a = &i;
*a++;
cout << *a;
cin.get();
return 0;
}
Can anybody explain why ?
++ has a higher operator precedence than the pointer dereference operator *.
So what *a++ does is to return the value of i (the old value of *a) before incrementing the pointer value.
After that expression has been evaluated, a now points to something other than the address of i, and the behaviour of a subsequent *a is undefined.
If you want to increment i via the pointer, then use (*a)++;
If you want your output to be "43", than you have to change *a++; to (*a)++;.
But other than for testing and learning, code like yours is more of a "C thing" than a "C++ thing". C++ offers another approach to referencing data and operating on it, through what the language calls “references”.
int i=42;
int &a=i; // ‘a’ is a reference to ‘i’
a++;
assert(i==43); // Assertion will not fail
References are especially useful for passing arguments to functions, without the risk of having null or displaced pointers.
What does "I'm getting adress" mean?
Have you checked out order of operations?
http://en.cppreference.com/w/cpp/language/operator_precedence
++-postfix is a higher precedence than *-dereference - hence:
*a++;
is really:
*(a++);
and not:
(*a)++;
... as you probably meant. Which is IMHO why I always recommend erring on the side of too many parentheses rather than too few. Be explicit as to what you mean :)
You have used *a++;
As your increment operator ++ has higher precedence than your pointer *, what actually is happening is that your pointer address is being incremented. So the new *a has no defined value and hence it will give an undefined value
*a++; is the equivalent of a++;
To fix this you can use parentheses (*a)++; or simply us pre increment operator ++*a;
Your code works fine till you reach the line
*a++;
As you know, C++ compiler will break this code of line as
*a = *(a+1);
That is, it will first increment address value of a and then assign the value to *a. But if you do,
*(a)++;
then you will get correct output, that is, 43.
For output- http://ideone.com/QFBjTZ

Strange operator with pointers

I was reading some code and came across this thing. I don't have the whole context now save this line.
cout<<(*--*++ptr+1)<< endl;
this compiles fine and works when we input values in it..
its declaration is like this.
char ***ptr ;
What is this operator and is it included in the standard?
It's not a single operator, it's a combination of several unary operators. It gets parsed like this:
*(--(*(++ptr))) + 1
So, ptr1 is first incremented, then dereferenced, then that value is decremented and dereferenced again.

What does "*ptrInt ++" do?

I'm implementing a template pointer wrapper similar in functionaltiy to boost::shared_ptr.
I have a pointer to an integer ptrInt.
What I want to do: Increment the integer ptrInt points to.
My initial code was this: *ptrInt ++;, although I also tried the same using (*ptrInt) ++;
Apparently, however, this doesn't seem to do what I expected it to.
In the end I got it working using *ptrInt += 1;, however I'm asking myself:
What exactly does *ptrInt ++; do?
Is there a more elegant solution to using *ptrInt += 1;?
*p++ // Return value of object that p points to and then increment the pointer
(*p)++ // As above, but increment the object afterwards, not the pointer
*p += 1 // Add one to the object p points to
The final two both increment the object, so I'm not sure why you didn't think it worked. If the expression is used as a value, the final form will return the value after being incremented but the others return the value before.
x = (*p)++; // original value in x
(*p)++;
x = *p; // new value in X
or
x = ++*p; // increment object and store new value in x
*ptr++ equivalent to *(ptr++)
*ptrInt ++ will
increment ptrInt by 1
dereference old value of ptrInt
and (*ptrInt) ++ as well as *ptrInt += 1 will do what you want.
See Operator Precedence.
(*ptr)++ should do it, unless you are using its value right away. Use ++*ptr then, which is equivalent to ++(*ptr) due to right-to-left associativity.
On a side note, here is my smart pointer implementation, perhaps it can help you in writing your own.
The expression is evaluated using the rules for operator precedence.
The postfix version of ++ (the one where ++ comes after the variable) has a higher precedence than the * operator (indirection).
That is why *ptr++ is equivalent to *(ptr++).
You want (*ptrInt)++, which increments the object, which generally does the same as *ptrInt += 1. Maybe you have overloaded the += operator, but not the ++ operators (postfix and prefix increment operators)?
The more elegant way is whatever you tried before. i.e (*ptrInt) ++;
Since, you aren't satisfied with that, it might be because of the post - increment.
Say, std::cout<<(*ptrInt) ++; would have shown you the un-incremented value.
So, try giving ++(*ptrInt); which might behave as you expected.
*ptrInt++ in your case does increment the pointer, nothing more (before that it fetches the value from the location at throws it away. of course if you use it in a more complex expression it will use it)
(*ptrInt)++ does what you are looking for.

What is the difference between the dot (.) operator and -> in C++? [duplicate]

This question already has answers here:
What can I use instead of the arrow operator, `->`?
(7 answers)
Closed 5 years ago.
What is the difference between the dot (.) operator and -> in C++?
foo->bar() is the same as (*foo).bar().
The parenthesizes above are necessary because of the binding strength of the * and . operators.
*foo.bar() wouldn't work because Dot (.) operator is evaluated first (see operator precedence)
The Dot (.) operator can't be overloaded, arrow (->) operator can be overloaded.
The Dot (.) operator can't be applied to pointers.
Also see: What is the arrow operator (->) synonym for in C++?
For a pointer, we could just use
*pointervariable.foo
But the . operator has greater precedence than the * operator, so . is evaluated first. So we need to force this with parenthesis:
(*pointervariable).foo
But typing the ()'s all the time is hard, so they developed -> as a shortcut to say the same thing. If you are accessing a property of an object or object reference, use . If you are accessing a property of an object through a pointer, use ->
Dot operator can't be overloaded, arrow operator can be overloaded. Arrow operator is generally meant to be applied to pointers (or objects that behave like pointers, like smart pointers). Dot operator can't be applied to pointers.
EDIT
When applied to pointer arrow operator is equivalent to applying dot operator to pointee e.g. ptr->field is equivalent to (*ptr).field.
The arrow operator is like dot, except it dereferences a pointer first. foo.bar() calls method bar() on object foo, foo->bar calls method bar on the object pointed to by pointer foo.
The . operator is for direct member access.
object.Field
The arrow dereferences a pointer so you can access the object/memory it is pointing to
pClass->Field
pSomething->someMember
is equivalent to
(*pSomething).someMember
Use -> when you have a pointer.
Use . when you have structure (class).
When you want to point attribute that belongs to structure use .:
structure.attribute
When you want to point to an attribute that has reference to memory by pointer use -> :
pointer->method;
or same as:
(*pointer).method
The target.
dot works on objects; arrow works on pointers to objects.
std::string str("foo");
std::string * pstr = new std::string("foo");
str.size ();
pstr->size ();
Note that the -> operator cannot be used for certain things, for instance, accessing operator[].
#include <vector>
int main()
{
std::vector<int> iVec;
iVec.push_back(42);
std::vector<int>* iVecPtr = &iVec;
//int i = iVecPtr->[0]; // Does not compile
int i = (*iVecPtr)[0]; // Compiles.
}
It's simple, whenever you see
x->y
know it is the same as
(*x).y
The -> is simply syntactic sugar for a pointer dereference,
As others have said:
pointer->method();
is a simple method of saying:
(*pointer).method();
For more pointer fun, check out Binky, and his magic wand of dereferencing:
http://www.youtube.com/watch?v=UvoHwFvAvQE
The simplest difference between the two is that "->" dereferences a pointer before it goes to look at that objects fields, function etc. whereas "." doesn't dereference first. Use "->" when you have a pointer to an object, and use "." when you're working with the actual instance of an object.
Another equivalent way of wrinting this might be to use the dereferencing "*" on the pointer first and then just use the ".". We skip middleman by using "->".
There are other differences, but the other answers have covered this extensively.
If you have a background in Java this might confuse you, since, in Java, everything is pointers. This means that there's no reason to have symbol that doesn't dereference your pointer first. In c++ however you gotta be a little more careful with remembering what is and what isn't a pointer, and it might be a good idea to label them with the prefix "p_" or simply "p".
The . (dot) operator is usually used to get a field / call a method from an instance of class (or a static field / method of a class).
p.myField, p.myMethod() - p instance of a class
The -> (arrow) operator is used to get a field / call a method from the content pointed by the class.
p->myField, p->myMethod() - p points to a class
The -> operator is used when we are working with a pointer and the dot is used otherwise.
So if we have a struct class like:
struct class{ int num_students; int yr_grad; };
and we have an instance of a class* curr_class (class pointer), then to get access to number of students we would do
cout << curr_class->num_students << endl;
In case we had a simple class object , say class_2016, we would do
cout << class_2016.num_students << endl;
For the pointer to class the -> operator is equivalent to
(*obj).mem_var
Note: For a class, the way to access member functions of the class will also be the same way