views:

213

answers:

8

can someone tell me what is the different between (*ptr).field and ptr->field? I know it connect somehow to static and dynamic linking, but i dont know what is it. can someone tell me the differnet and give me an example?

edit: if i have this code:

Point p;       //point is a class that derive from class shape 
Shape *s=&p; 
               //there is a diffrence if i write:

(*s).print();  //print is virtual func
s->print();    // the answers will not be the same, why?

TNX!

+4  A: 

it has nothing to do with static or dynamic linking both expressions will return the value of ptr.field

the ptr->field form is an abbreviated syntax for accessing a member directly from a pointer

UPDATE: it occurred to me that your original intent was not linking but binding if this indeed was what you were aiming to then there is static binding and dynamic binding which have some relation to the -> operator see here

Alon
Yes, but abbreviated for (*ptr).fld, not for *ptr.field.
ChrisInEdmonton
It's important to note that these are NOT necessarily equivalent, due to the possibility to overload operator* and operator-> in C++!
Hostile Fork
@Hostile Fork: Which is why, in some shops, C++ code review sessions should include electroshock therapy machines.
David Thornley
yesss!! that's what i meant! TNX!
glad we pieced it together at the end ;-)
Alon
+1 for figuring out the original meaning. Well done.
ChrisInEdmonton
+2  A: 

Static linking is the result of the linker copying all library routines used in the program into the executable image. This may require more disk space and memory than dynamic linking, but is both faster and more portable, since it does not require the presence of the library on the system where it is run.

Dynamic linking is accomplished by placing the name of a sharable library in the executable image. Actual linking with the library routines does not occur until the image is run, when both the executable and the library are placed in memory. An advantage of dynamic linking is that multiple programs can share a single copy of the library.

But it is unrelated to pointer indirection you've mentioned -- in fact, those two expressions are identical.

vehomzzz
Not quite. ptr->field is identical to (*ptr).field, not to *ptr.field.
ChrisInEdmonton
A: 

They are both the same.
*ptr.field dereferences the variable ptr then returns the value of member field.

The -> operator is shorthand notation for the above.

Thomas Matthews
Actually, `*ptr.field` is evaluated as `*(ptr.field)`, not `(*ptr).field`.
Shmoopty
+1  A: 

This has nothing to do with linking.

ptr->fld 

is merely shorthand for

(*ptr).fld

It's pure syntactic sugar ;)

John Knoeller
In particular, see § 5.2.5.3 of the C++ standard.
outis
§ 5.2.5 3 If E1 has the type “pointer to classX,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot).
outis
@outis: The part you quoted desribes the behavior of the *built-in* operator `->`. Don't forget that `->` in C++ does not necessarily refer to the built-in operator. It can also be overloaded by the user. The OP did not say that `ptr` is of raw pointer type.
AndreyT
I didn't forget that. Since the quotation states that the equivalence applies when `ptr` is a pointer, I didn't bother to say it in my own words.
outis
+2  A: 

I assume that by *ptr.field you meant (*ptr).field.

As far as only built-in operators are considered, there's no difference between the two. And no, it has nothing to do with and "static" or "dynamic" linking, whatever is implied by these terms.

The only potential difference between the two is that in ptr->field variant -> is an overloadable operator in C++, while in the (*ptr).field variant only * is overloadable, while . is not.

Also, some differences between these two methods of member access existed in very archaic versions of C language (CRM C), but I doubt anyone cares about those today.

AndreyT
+1  A: 

As long as ptr is a pointer, the two are equivalent once properly parenthesized (as others have said). If ptr is an object, rather than a pointer, they might be different depending on definitions for operator* and operator-> (if any) from the object's class or ancestors.

outis
ok, if i have this code:Point p;//point is a class that derive from class shapeShape *s=there is a diffrence if i write (*s).print();//print is virtual functo s->print();the answers will not be the same, why?
+7  A: 

This has nothing to do with static or dynamic linking.

See C++'s operator precedence. The . has a lower precedence than *, so there's actually quite a difference between *ptr.fld and ptr->fld. For example, the following code demonstrates:

#include <iostream>

struct foo {
  int f;
};

int main() {
  struct foo *p = new struct foo;
  p->f = 42;
  std::cout << p->f << std::endl;
  std::cout << (*p).f << std::endl;
  // The following will not compile
  // std::cout << *p.f << std::endl;
}

As John Knoeller points out, ptr->fld is syntactic sugar for (*(ptr)).fld, but is not the same as *ptr.fld, which would actually evaluate to *(ptr.fld), probably not what you want.

You'd use ptr->fld when you have a pointer to a structure and want to access a field contained therein. (*(ptr)).fld means the same thing but is not as tidy. You'd use *strct.fld when you have a structure, not a pointer to a structure, that contains a field (fld) which is a pointer you want to dereference. The case of ptr->fld is shown above. The case of *strct.fld could be used with the following structure:

struct foo {
  int *fld;
}

struct foo f;
f.fld = new int;
*f.fld = 42;
ChrisInEdmonton
As pointed out by outis, ptr->field is actually syntatic sugar for (*(ptr)).field, not for (*ptr).field. Ooops. Fixed.
ChrisInEdmonton
Since `ptr` is an identifier, `(*ptr).field` is fine. Still, it's good to point out the general case.
outis
The OP confirmed that he actually meant `(*ptr).field`. I edited the question.
AndreyT
+1  A: 

The form -> is just shorthand for de-refrencing the pointer and accessing the member.

(*ptr).field;
// Equiv to 
ptr->field;

One good reason for using -> is that when you are following a chain:

int x = (*(*(*(*ptr).field1).field2).field3).field4;
// Equiv to 
int y = ptr->field1->field2->field3->field4;

The second one becomes much more readable.

As for the second part of your question.
I find it really easy to just nock up an example.

#include <iostream>

class Shape
{
    public:   virtual ~Shape()        {}
              virtual void Print()    {std::cout << "Shape\n";}
};
class Point: public Shape
{
    public:   virtual void Print()    {std::cout << "Point\n";}
};

int main ()
{
    Point   p;
    Shape*  s = &p;

    s->Print();
    (*s).Print();
}

> vi x.cpp
> g++ x.cpp
> ./a.exe
Point
Point

As you can see the result is the same in both situations.

When you call a method via a pointer or a reference the virtual call mechanism will be invoked. The star operator (AKA derefence operator) returns a reference to an object (it does not actually de-reference the object). So when it is used to call a method the virtual call mechanism will be invoked and the most derived version of the method called.

Martin York
ok, tanks, although my DR. said there is some different, but i cant remember what...
There is no difference between (*ptr)->f1 and ptr->f1. That is defined by the standard. If we move to virtual functions. There re situations where the virtal call mechanism will not be used, but this is not one of them.
Martin York
so what is the case that the virtal call mechanism will not be used?
When you name it explicitly (I forget the term). But a method in Point can call Shape::Print() or Point::Print() to get a specific version of the method.
Martin York
Are you thinking of "qualified name"? Or perhaps "explicit scope resolution"?
outis