Question

it's passed a lot since i used c++ so here the(probally dumb) question:

A basic smart pointer Object should behave like a normal pointer one, so in a typical implementation we add the * and -> operator to the object, something like this:

template <class T> class auto_ptr
{
    T* ptr;
    public:
    explicit auto_ptr(T* p = 0) : ptr(p) {}
    ~auto_ptr()                 {delete ptr;}
    T& operator*()              {return *ptr;}
    T* operator->()             {return ptr;}
   // ...
};

Now, in my knowings, the c++ * operator (dereference) stands for: "get the value pointed in the heap by the value of ptr" (is it right?), and the type of *ptr should be T. So why we would return an address?

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

Instead of:

T operator*()              {return *ptr;}

Second, by having the following snippet:

void foo()
{
    auto_ptr<MyClass> p(new MyClass);
    p->DoSomething();
}

Now, how can i access ptr->DoSomething() method by just writing p->DoSomething()? Logically i would come writing the wrong code:

p->->DoSomething();

Because p-> returns a T* and then i need another -> operator for access the DoSomething() method.

Thanks for any answer/clarification and sorry for eventually bad English.

Was it helpful?

Solution

In C++, when you evaluate a function, you end up with a value (unless the function's return type is void). The type of a value is always an object type. So when you say f(), that expression is a value of type T. However, there are different categories of value:

T    f();    =>   f() is a prvalue, passed along by copy
T &  f();    =>   f() is an lvalue, the same object that is bound to "return"
T && f();    =>   f() is an xvalue, the same object that is bound to "return"

So if you want a function to produce an existing value that you don't want to copy, you have to declare the return type of the function as one of the reference types. If the return type is not a reference type, then a copy of the return value will be made, and the caller only ever sees that copy.

OTHER TIPS

The dereference operator returns a reference because then you can do e.g.

*somePointer = someValue;

and the value of what somePointer points to would change to someValue. If you returned by value, the above expression would have a temporary value that is assigned to, and then that temporary value is destructed and the change is lost.

The reason you don't have to write p->->DoSomething is that operator-> recurses until it finds something that isn't a pointer, T*.

p-> finds T* which is a pointer so it goes down another level and finds a MyClass-object, so it stops and does a normal operator. on that.

Note that smart pointers aren't considered pointers in this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top