when I have a pointer like:
MyClass * pRags = new MyClass;
So i can use
pRags->foo()
or
(*pRags).foo()
to call foo.
Why these 2 are identical? and what is *pRags?
Thank you
Why are these two identical?
They are equivalent because the spec says they are equivalent. The built-in -> is defined in terms of the built-in * and ..
What is *pRags?
It is the MyClass object pointed to by pRags. The * dereferences the pointer, yielding the pointed-to object.
For more information, consider picking up a good introductory C++ book.
In addition to the other answers, the '->' is there for convenience. Dereferencing a pointer to an object every time you access a class variable for function is quite ugly, inconvenient, and potentially more confusing.
For instance:
(*(*(*car).engine).flux_capacitor).init()
vs
car->engine->flux_capacitor->init()
pRags->foo() is defined as syntactic sugar that is equivalent to (*pRags).foo().
the * operator dereferences a pointer. That is, it says that you're operating on what the pointer points to, not the pointer itself.
The -> is just a convenient way to write (*).. and *pRags is the object at the address stored in pRags.
Yes they are identical. -> was included in C (and thus inherited into C++) as a notational convenience.
* in that context is used to dereference a pointer.
Unary * is known as the dereferencing operator. Dereferencing a pointer turns a T* into a T&; dereferencing an object invokes that object type's unary operator* on that object value if one is defined, or gives an error otherwise.
(*pRags) that goes through the pointer pRags and get you whole object, so on that you could use regular dot notation . .
pRags is a pointer of type MyClass. Just like you can have pointers for primitive data types, e.g. int ptr, you can also have pointers to objects and in this case represented by pRags. Now accessing the object "members" is done using the arrow operator (->) or you can use the "." and dereference "*" to access the object's member values. Here a member is a variable inside MyClass. So, foo() would have a definition inside MyClass.
Related
I came across this function in 'The C++ programming language' book.
template<typename In, typename Out>
Out uninitialized_move(In b, In e, Out oo) {
using T = Value_type<Out>; // assume suitably defined type function (§5.4.2.1, §28.2.4)
for (; b!=e; ++b,++oo) {
new(static_cast<void*>(&*oo)) T{move(*b)}; // move construct
b–>~T(); // destroy
}
return oo;
}
The placement new parameter is &*oo
Why does it need &* in that statement
?
Why won't just passing 'oo' work?
In case oo isn't a pointer and has no operator T*() overload, you can't pass it directly as a pointer.
Some class objects, particularly iterators (like std::vector::iterator), implements something like
SomeStuff& SomeClass::operator*(void);
so that they can be "dereferenced" as if they were pointers. This is called operator overloading.
If you want to pass it directly, you must ensure there's such a member function like
SomeClass::operator T*(void);
In this way such objects can be implicitly converted to the corresponding pointers by calling that function. Otherwise you have to "dereference" it and then take the address of the dereferenced object.
Although you are correct about & and * cancelling each other out for pointers, uninitialized_move is a template function, so oo could be of non-pointer type that has a custom dereference operator *, e.g. an iterator.
For types like that an explicit "round-trip" is required to ensure that static_cast is applied to a pointer.
Wondering through the LLVM source code i stumbled upon this line of code
MachineInstr *MI = &*I;
I am kinda newb in c++ and the difference between references and pointers is quite obscure to me, and I think that it has something to do about this difference, but this operation makes no sense to me. Does anybody have an explanation for doing that?
The type of I is probably some sort of iterator or smart pointer which has the unary operator*() overloaded to yield a MachineInstr&. If you want to get a built-in pointer to the object referenced by I you get a reference to the object using *I and then you take the address of this reference, using &*I.
C++ allows overloading of the dereference operator, so it is using the overloaded method on the object, and then it is taking the address of the result and putting it into the pointer.
This statement:
MachineInstr *MI = &*I;
Dereferences I with *, and gets the address of its result with & then assigns it to MI which is a pointer to MachineInstr. It looks like I is an iterator, so *I is the value stored in a container since iterators define the * operator to return the item at iteration point. The container (e.g. a list) must be containing a MachineInstr. This might be a std::list<MachineInstr>.
Let us say I have:
// This is all valid in C++11.
struct Foo {
int i = 42;
int& j = i;
};
// Let's take a pointer to the member "j".
auto b = &Foo::j; // Compiler is not happy here
// Note that if I tried to get a pointer to member "i", it would work, as expected.
Foo f;
std::cout << f.*b; // Try using the pointer to member
The compiler complains that I cannot take the address of the member because it is a reference. To be precise:
Semantic Issue: Cannot form a pointer-to-member to member 'j' of reference type 'int &'
I know doing this seems pointless, but I am only wondering why it cannot be done.
Why is this impossible?
It cannot be done because you cannot take a pointer to a reference- period.
If you could take a member pointer to a reference, this would be inconsistent with the behaviour of references on the stack. The attitude of C++ is that references do not exist. As such, you cannot form a pointer to them- ever.
For example, &f::a would have to be different to &f::b. And by de-referencing &f::b, you would effectively be achieving a pointer to a reference, which is not allowed.
C++11 standard:
§8.3.3 p3 [dcl.mptr]
A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or “cv void.”
Also, in general:
§8.3.1 p4 [dcl.ptr]
[ Note: There are no pointers to references; see 8.3.2. [...] —end note ]
§8.3.2 p5 [dcl.ref]
There shall be no references to references, no arrays of references, and no pointers to references.
Member pointer (as opposed to a simple pointer to a member) is simply an offset into the structure, not a pointer at all. You can get data through it only in conjunction with the structure itself (or a pointer to a structure): the value of the offset is added to the address of the structure, and the result is dereferenced to produce the value of the member.
Now suppose a member is a reference, so accessing data through it already requires a dereference (compiler hides it from us, but it needs to spit out the corresponding instructions in its output). If C++ were to allow member pointers to references, they'd be of yet another type: an offset that needs to be added to the base, and then dereferenced twice. It is too much work to improve an already obscure feature; prohibiting it is a much better way out.
Allowing you to make a pointer to a reference does not give you any expressive power. There's nothing you can do with such a beast that you can't easily do with a reference or with a pointer. All you get out of it is added complexity.
And making a pointer to a member that is a reference is not allowed for consistency with the rule that forbids pointers to references, and because it adds even more complexity. The designers of the language probably decided that the little gains you get from these was not worth it.
This is totally just my opinion.
static void increment(long long *n){
(*n)++;
}
struct test{
void (*work_fn)(long long *);
};
struct test t1;
t1.work_fn = increment;
How do I actually call the function now? t1.work_fn(&n) ?
How do I actually call the function now? t1.work_fn(&n) ?
That'll work just fine.
Function pointers don't need to be explicitly dereferenced. This is because even when calling a function normally (using the actual name of the function), you're really calling it through the pointer to the function. C99 6.5.22 "Function calls" says (emphasis mine):
The expression that denotes the called function (footnote 77) shall have type pointer to function returning void or returning an object type other than an array type
Footnote 77:
Most often, this is the result of converting an identifier that is a function designator.
Note that you still can dereference the function pointer (or a normal function name - though I think you'd cause much confusion doing so) to call a function because C99 6.5.3.2/4 "Address and indirection operators" says:
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator
So all of these will end up doing the same thing (though the compiler might not be able to optimize the calls-through t1.work_fn as well):
t1.work_fn(&n);
(*t1.work_fn)(&n);
increment(&n);
(*increment)(&n);
You can call it as t1.work_fn(&n) or as (*t1.work_fn)(&n), whichever you prefer.
Symmetrically, when assigning the pointer you can do either t1.work_fn = increment or t1.work_fn = &increment. Again, it is a matter of personal coding style.
One can probably argue that for the sake of consistency one should stick to either "minimalistic" style
t1.work_fn = increment;
t1.work_fn(&n);
or to a "maximalistic" style
t1.work_fn = &increment;
(*t1.work_fn)(&n);
but not a mix of the two, so that we can have well-defined holy wars between two distinctive camps instead of four.
P.S. Of course, the "minimalistic" style is the only proper one. And one must crack eggs on the pointy end.
Yes, that's how to call it. Function names and variables containing function pointers are essentially the same thing.
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