Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does &**this return exactly?

Tags:

c++

pointers

this is a pointer to the calling object (it returns the r-value).

*this is a pointer to the pointer of the calling object (it returns the value of the address).

**this is a pointer to the pointer of the pointer of the calling object (???).

&***this is a reference to the pointer of the pointer of the pointer of the calling object (???).

std::vector<int>:: iterator i = vector1.begin();

i is the pointer to its own r-value (returns its own value).

*i is the pointer of a r-value of an object contained in a vector (returns the value pointed in &value).

**i is the pointer to the pointer of a r-value of an object contained in a vector (???).

I am really confused.

Here's a sample code where we find the expression &**this:

class _Iter
{
private:
    ListElem *pCurr;
    const List *pList;

public:
    _Iter(ListElem *pCurr, const List *list)
        : pCurr_(pCurr), pList(list)
    {}

    T& operator*() { return pCurr_->data; }
    T* operator->() { return &**this; }
};
like image 866
user2967016 Avatar asked Mar 13 '14 03:03

user2967016


2 Answers

this is a pointer to the current object.

*this is a reference to the current object, i.e. this dereferenced.

**this is the returned value of the overloaded unary operator* function called on the current object.

If the object returned from **this has an overloaded operator&() function, then &**this evaluates to the returned value of (**this).operator&(). Otherwise, &**this is the pointer to the returned value of the overloaded unary operator* function called on the current object.

Example:

#include <iostream>

struct A
{
   int b;
   int a;
   int& operator*() {return a;}

   int* test()
   {
      return &**this;
   }
};

int main()
{
   A a;
   std::cout << "Address of a.a: " << a.test() << std::endl;
   std::cout << "Address of a.a: " << &(*a) << std::endl;
   std::cout << "Address of a.a: " << &(a.a) << std::endl;
   return 0;
}

Sample output:

Address of a.a: 0x7fffbc200754
Address of a.a: 0x7fffbc200754
Address of a.a: 0x7fffbc200754
like image 67
R Sahu Avatar answered Sep 27 '22 23:09

R Sahu


If you have a class Foo and a method of this class that use this and the object Foo obj then

this - is a value of type pointer to Foo that has a value of address of object obj

so you can write like this (for example in Foo:test()):

Foo *addr = this;

so addris a variable of type pointer to Foo that is initialized with a address value of object obj of class Foo.

All pointers in C++ can be dereferenced with *. So when you dereference a pointer to an object you get that object

Foo *addr = get_pointer_to(obj); //function that return a pointer to object

//three equivalent ways to call someMethod() of object obj of class Foo
obj.someMethod();
addr->someMethod();
(*addr).someMethod();

Upper part of code illustrates that object obj and dereferenced pointer (*addr) have the same syntax, because they are the same object.

C++ allows you to overload different language operators. So when you write (**this) the compiler looks to this and find that this is type of pointer to Foo, so dereferencing *this gives object of type Foo. Then the compiler find (* (*this)). But Foo is not a type of the pointer, so by default there is no * operator. So the compiler will returen an error and break the compilation. But if you define(overload) operator*() in class Foo then the compiler will call this method. So **this is equivalent to this->operator*() or to (*this).operator*().

The last one is operator&(). By default this operator returns a pointer to object. But of course it can be overloaded and return something else. So &**this can return 1) an address of object that was returned by operator*() applied to the object (*this)
2) return value of method operator&() of the object that was returned by operator*() which was applied to (*this).

If there is no operator*() defined then &**this won't compile.

In addition if there is no operator*() defined and no operator&() defined then the construction of &**some_pointer will either not compile or will return (*some_pointer). And I can guarantee that (*some_pointer) will be a pointer.

like image 42
JustAnotherCurious Avatar answered Sep 27 '22 22:09

JustAnotherCurious