2

My background is in more managed languages (C#, python) but I am becoming more experienced in C/C++. I am familiar with why the selection by reference (.) and selection through pointer operation (->) operators are different. In all cases I have encountered, if you use the incorrect one, it will result in a compile error. If that is the case, they why were they not made into one operator? Is there a case where using either on the same object results in different, meaningful and useful results?

This question inspired by this answer: Is this right way to call a function in c++?

Community
  • 1
  • 1
escapecharacter
  • 954
  • 2
  • 12
  • 29
  • "they why were they not made into one operator?" -- Calls for speculation about the minds of the original designers of C and its predecessors. They certainly *could have been* the same operator, but perhaps the designers thought it would be confusing, or didn't even think of the possibility. – Jim Balter Jul 09 '13 at 14:05
  • about 'duplicate' - sorry, I've misread the question and marked it originally with wrong target.. Actually, it's more of a duplicate of http://stackoverflow.com/questions/1238613/what-is-the-difference-between-the-dot-operator-and-in-c or http://stackoverflow.com/questions/4984600/when-do-i-use-a-dot-arrow-or-double-colon-to-refer-to-members-of-a-class-in-c – quetzalcoatl Jul 09 '13 at 14:12

4 Answers4

3

In C++ you can overload the ->-operator, which is used in pretty much all smart pointer implementations. However, some of those also have their own methods, i.e. to release a reference.

struct test {
    int x;
};

std::shared_ptr<int> ptr(new test);

// Write to member x of the allocated object
ptr->x = 3;
// Reset the shared pointer to point to a different object.
// If there are no further shared_ptrs pointing to the previously allocated one,
// it is deleted.
ptr.reset(new test)

Additionally, it would be quite messy for the compiler to resolve operator-. for something like multiple-level pointers, i.e. test*** ptr. With your logic, ptr.x, (*ptr).x, (**ptr).x and (***ptr).x would all be the same.

filmor
  • 30,840
  • 6
  • 50
  • 48
3

You cannot apply -> to a reference to a basic type and you cannot apply . to a pointer, but you can apply both to a user-defined type and they will have different meanings. The simplest example is a smart pointer, like std::shared_ptr:

struct A { int x; };

std::shared_ptr<A> p(new A);
p->x = 10;
p.reset();
Mikhail
  • 20,685
  • 7
  • 70
  • 146
2

Is there a case where element selection by reference and element selection through pointer operation are both valid?

Since you can overload operator->() in C++, you can actually arrive at situations where you can use -> and . interchangeably on the same object. You can even engineer things so that you get a different result, as per this example:

#include <iostream>

struct Bar
{
  void hello() const { std::cout << "Bar!!!\n"; }
};

struct FooBar
{
  Bar bar;
  void hello() const { std::cout << "FooBar!!!\n"; }
  const Bar* operator->() const {return &bar; }
};

int main()
{
  FooBar fb;
  fb->hello();
  fb.hello();
}

Of course, in real code you would never do something as crazy as this (although I have seen this kind of thing in "production" code).

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

the short answer would be a smart pointer

you can access the smart pointer class arguments using the "." (if you make your own smart pointer class you can extract from there for instance the current reference count) while you would use the "->" operator to access whatever is being stored using the smart pointer.