C++ overloading dereference operators

I'm relatively new to C++, still trying to get a hang of the syntax. I've been taking a look at a few operator overloading examples, most recently smart pointer implementations. Here's a really generic example I'm looking at:

template < typename T > class SP
{
    private:
    T*    pData; // Generic pointer to be stored
    public:
    SP(T* pValue) : pData(pValue)
    {
    }
    ~SP()
    {
        delete pData;
    }

    T& operator* ()
    {
        return *pData;
    }

    T* operator-> ()
    {
        return pData;
    }
};

When overloading the dereference operator why is the type T&? Similarly, when overloading the structure dereference why is the type T*?

The dereference operator (*) overload works like any other operator overload. If you want to be able to modify the dereferenced value, you need to return a non-const reference. This way *sp = value will actually modify the value pointed to by sp.pData and not a temporary value generated by the compiler.

The structure dereference operator (->) overload is a special case of operator overloading. The operator is actually invoked in a loop until a real pointer is returned, and then that real pointer is dereferenced. I guess this was just the only way they could think of to implement it and it turned out a bit hackish. It has some interesting properties, though. Suppose you had the following classes:

struct A {
    int foo, bar;
};

struct B {
    A a;
    A *operator->() { return &a; }
};

struct C {
    B b;
    B operator->() { return b; }
};

struct D {
    C c;
    C operator->() { return c; }
};

If you had an object d of type D, calling d->bar would first call D::operator->(), then C::operator->(), and then B::operator->(), which finally returns a real pointer to struct A, and its bar member is dereferenced in the normal manner. Note that in the following:

struct E1 {
    int foo, bar;
    E1 operator->() { return *this; }
};

Calling e->bar, where e is of type E1, produces an infinite loop. If you wanted to actually dereference e.bar, you would need to do this:

struct E2 {
    int foo, bar;
    E2 *operator->() { return this; }
};

To summarize:

  1. When overloading the dereference operator, the type should be T& because that is necessary to modify the value pointed to by pData.
  2. When overloading the structure dereference, the type should be T* because this operator is a special case and that is just how it works.

C Programming Tutorial for Beginners, This course will give you a full introduction into all of the core concepts in the C programming Duration: 3:46:13 Posted: 15-Aug-2018 C or c is the third letter in the English and ISO basic Latin alphabets. Its name in English is cee (pronounced / ˈsiː /), plural cees.

The purpose of dereference operator is to dereference a pointer and returns the object reference. Hence it must return the reference. That is why it is T&.

The purpose of referring operator (->) is to return a pointer and hence T* is returned.

Learn C Programming, C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on. C-- (pronounced cee minus minus) is a C -like programming language. Its creators, functional programming researchers Simon Peyton Jones and Norman Ramsey, designed it to be generated mainly by compilers for very high-level languages rather than written by human programmers.

It is because pointer contains an address of a variable referencing it will give a reference (or to say a lvalue refrence) to the address it has stored. e.g. int x; int *p; p=&x; now x and *p can be used interchangeably. if you do x =4; or *p = 4; both will have same result. *p works as a reference to x just like a normal reference int& t = x; will work.

Next thing structure dereference operator. This operator gives you the access of member variables through a pointer to object of a class. In above example the member is T* pData; so using this operator will give access to pData and pData is T* so the return type is T*. if pData in above example would have been T then the return type would have been T.

C Tutorial, C programming is a general-purpose, procedural, imperative computer programming language developed in 1972 by Dennis M. This is a list of operators in the C and C++ programming languages.All the operators listed exist in C++; the fourth column "Included in C", states whether an operator is also present in C. Note that C does not support operator overloading.

Overloaded operators are just functions

When overloading operaters you are free to return anything basicly (just like any other function), with the noteable exception of member of pointer -> being somewhat special in this way.

In the example you show, a smart pointer, you aim to mimick the syntax of a pointer (pointer semantic). Then for syntax like:

*p = 2;

The indirection operator* return a non-const reference to object and we are able to modify through operator*. In effect, usually used for proxy type classes in the same way and it is a sort of a convention - but you could in theory return whatever.

The member of pointer operator -> is a bit tricky. See this answer for an explanation.

Learn C, learn-c.org is a free interactive C tutorial for people who want to learn C, fast. As well as C and Simula's influences, other languages also influenced this new language, including ALGOL 68, Ada, CLU and ML . Initially, Stroustrup's "C with Classes" added features to the C compiler, Cpre, including classes, derived classes, strong typing, inlining and default arguments.

We are making smart pointer and our aim is to access member of class/structure using any of this T& (reference) or T* (pointer) with flexibility.

for T* operator-> ():

T* operator-> ()
{
  return pData;
}
arrow operator (->) is a shorthand for (*p) and hence we return *pData which is of   type T*. 
here we are Overloding arrow operator so that members of T can be accessed like a pointer.

for T& operator* ():

T& operator* ()
{
  return *pData;
}
    * is "value at address" operator, here we are Overloding * (pointer) operator so 
    that members can be accessed  through a reference (T&).

We can change the behavior of the operator with operator overloading but its not recommended. overloaded operator behavior should be as close as its basic functionality.

Cprogramming.com: Learn C and C++ Programming, The best site for C and C++ programming. Popular, beginner-friendly C and C++ tutorials to help you become an expert! Programming Languages Development - C++ has been used extensively in developing new programming languages like C#, Java, JavaScript, Perl, UNIX’s C Shell, PHP and Python, and Verilog etc. Computation Programming - C++ is the best friends of scientists because of fast speed and computational efficiencies.

C Programming Language, This page contains all topics of C with clear explanations and examples. It also contains job interview questions, MCQ quizzes and output based questions. Microsoft C++, C, and Assembler documentation. Learn how to use C++, C, and assembly language to develop applications, services, and tools for your platforms and devices.

C Language Introduction, C++ is nearly a superset of C language (There are few programs that may compile in C, but not in C++). Beginning with C programming: Structure of a C program C# (pronounced see sharp, like the musical note C♯, but written with the number sign) is a general-purpose, multi-paradigm programming language encompassing strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.

Learn C Programming Language Tutorial, C programming is considered as the base for other programming languages, that is why it is known as mother language. It can be defined by the following ways:. Learn C# programming - for beginning developers, developers new to C#, and experienced C# / .NET developers

Comments
  • *p = 2 is often desired syntax. It would be a shame if it didn't do anything.
  • People usually at least attempt to forge consistency with there overloads. C++11 5.3.1p1 [expr.unary.op] lays out a * operator for pointer-types, and its not uncommon to mimic that (including overloads for const if you want to run the full gambit).
  • I think this question stems from the idea that "the purpose of operator-> is to return a pointer" is counter-intuitive. The confusion is that: "(*x)." and "x->" both ultimately dereference x and access a member of the dereferenced pointer. So the fact that one operator "is meant to" return a pointer and the other a reference isn't immediately obvious.
  • I interpret the added question "Why is C++ designed in such way that operator* and operator-> are different in return types?" like "Why does the operator->() overload also add a built-in dereferencing step if used via the built-in -> operator - when the overload could just return T& directly without adding any step afterwards (except adding an implied . between object and a mandatory member)".