views:

325

answers:

9

Possible Duplicate:
Why does C have a distinction between -> and . ?

What is the real reason for a programmer to have to differentiate between . and -> when accessing a member of an object?

void foo( Point &p ) {
    p.x ;
    p->y; // syntax error
} 

void foo( Point *p ) {
    p.x ; // syntax error
    p->y;
} 

I mean, one way or another, they both refer to an object, p.

  • Why do I have to bother checking every time what p is ? Can't the compiler understand ?

  • Why haven't they allowed it to accept . syntax for both? That would be fine for stack objects too.

And if it is due to C-tradition,

  • Why don't they allow both . and -> accessors?

For more than 15 years, I have always humbly considered the compiler errors as being my fault !

+2  A: 

Because pointers and references are different, and are treated differently ?

I appreciate the visual difference when I'm reading code.

luke
+7  A: 

Because p->d actually means (*p).d. It does a dereference and then a member access. References behave like objects thus they don't need dereferencing (they are also a C++ feature, while pointer are inherited from C); it has been kept that way for backwards compatibility.

C++ is full of inconsistencies like this, but there's usually no better choice to add new features and keep old code working. Rewriting the old code is not an option.

iconiK
Now imageine d is next an a linked list. `(*(*(*(*p).next).next).next).next` is the same as `p->next->next->next->next`
Martin York
+6  A: 

Because you might have a smart pointer. In that case, you can access the smart pointer's members using . and the real object's members using ->.

AraK
Isn't it the other way around - smart pointers taking advantage of this feature rather than the feature being there so that smart pointers can exist...
It could be both. C obviously distinguished between `.` and `->` before there were such things as smart pointers. But C++ *could* in principle have chosen to merge them as the OP suggested, allowing you to use either syntax. But then it'd be impossible to implement smart pointers
jalf
@user779 I would say you have a point :)
AraK
+4  A: 

They are not the same.

. is when you have an actual object.
-> is when you have a pointer to an object.

The . operator cannot be overloaded, while the -> operator can be overloaded.

abelenky
The OP's question isn't when to use what, but why the two different syntax forms exist in the first place.
jalf
+2  A: 

Consider the following piece of code:

x.myInt = 3;
cout << (int)&x <<< endl;

What are we printing here? The address of a pointer or the address of the object? I welcome the difference between . and -> because it gives you more context on the code.

With your suggested change we wouldn't know the difference without looking up what type x is.

Brian R. Bondy
Yes, this is an example of what I was referring to in my answer.
LarsH
+3  A: 

In theory, at least in C, the language could have been designed to do this. D (for one example) does exactly what you're asking about.

In C++, things could be a big uglier -- it's entirely possible for x->y and x.y to both be valid, but mean entirely different things (i.e., a smart pointer that overloads operator->):

#include <iostream>

class P { 
    class inner { 
    public:
        inner() : x(1) {}
        int x;
    } i;
public:
    int x;


    P() :x(0) {}

    inner *operator->() { return &i; }
};

int main() { 
    P p;
    std::cout << p.x << "\t" << p->x << "\n";
    return 0;
}
Jerry Coffin
+3  A: 

Smart pointers: they might have both members and point to some other values. For example:

boost::smart_ptr<someclass> x(new someclass())
x->some_method();
x.reset();
liori
+2  A: 

It's a matter of convenience: p->foo is the same as (*p).foo

It's like asking why have a ++ or a += operator when you can express the same logic with simple + and = operators.

Now imageine foo is next an a linked list. (*(*(*(*p).next).next).next).next is the same as p->next->next->next->next
Martin York
A: 

I can think of one reason: the more complex the mapping between what the developer wrote and what they actually wanted to happen, the more difficult it is to figure out what they really meant when there is a type or syntax error.

LarsH