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; }
};
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
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.
Related
I wonder, why don't we use only this without * in case of an overloaded assignment operator? If I use this only, it gives me a compiler error. Why we don't use * with arr[i], or any other variables, like return x in the 2nd and 3rd example?
Myclass &Myclass::operator=(const Myclass &rhs)
{
if(this==&rhs)
return *this;
}
double& setValues( int i ) {
return vals[i]; // return a reference to the ith element
}
int& setValues(int x) {
return x; // return address/reference of x
}
#logan_92: References, and pointers are a bit tricky: House& is a reference to a house somewhere ("That is Bob's house over there"). House* is a building address ("13931 Main Street"). Dereferencing a pointer is like driving to the building.
Likewise: this is a pointer. It is the address of a Myclass, it is not a Myclass itself. operator= returned a reference to a house, so you dereference it to go to the Myclass&, so that you can return the reference. It has nothing to do with being "inside the class" or "outside the class". The only difference is an address vs a reference.
One of the things you can do with pointers and addresses is get an offset. ("The house 3 down from 13931 Main Street"). The basic syntax is *(pointer+3). This turns out to be incredibly handy, so C made a special syntax for this: pointer[3]. It is a reference to the third object over from the address of pointer. As a result, this[0] is the same as *this. It's 0 objects over from the address.
#include <iostream>
using namespace std;
class Object
{
public:
Object() {}
void Print() const
{
cout << "const" << endl;
}
void Print()
{
cout << "mutable" << endl;
}
};
void print_obj(const Object& obj)
{
obj.Print();
}
int main()
{
Object obj1;
const Object obj2;
Object*const pobj1 = &obj1;
print_obj(obj1);
print_obj(obj2);
obj1.Print();
obj2.Print();
pobj1->Print();
return 0;
}
I know the output is
const
const
mutable
const
mutable
I guess for const object, it looks for the const function. Otherwise the mutable function. But why is the last one mutable?
But why is the last one mutable?
Object*const pobj1 = &obj1;
declares pobj1 to be a const pointer to a non-const object. The object is still mutable but the pointer is not.
After the variable is initialized, you will not be able to change it to point to another variable.
pobj1 = &obj2; // Not OK.
But you can still change the variable it points to and call non-const member functions of the class through the pointer.
*pobj1 = obj2; // OK
But why is the last one mutable?
This is because the declaration is Object* const pobj1. Since we are working with pointers there are 2 const possibilities.
const Object* const pobj1 OR Object const * const pobj1
^^1^^ ^^2^^ ^^1^^ ^^2^^
// 1 applies to the types (i.e., Object)
// 2, which is what you're using applies to the pointer, therefore you're using a non-const Object
This
Object*const pobj1 = &obj1;
declares pobj1 to be a const pointer to a non-const object. If you doubt that,
just change it to
Object*const pobj2 = &obj2;
This won't compile because it throws away a const qualifier of obj2.
BTW, the restriction is that for const object, it can ONLY use const functions. 'const' after the parenthesis means that 'this*' pointer will be treated as a pointer to a const object within the method.
For non-const objects, it can use both const and non-const methods, but it will chose to use non-const first (if both are defined).
I believe you meant "const Object*". "const" can be applied to the pointer and/or the object the pointer is pointing to. The twist is that "Object * const" is the same as "Object const*".
So far to my understanding, when defining a pointer variable, we are allocating space in RAM for that variable.
int *p;
Would define a space in RAM. Then we assign a memory address to that pointer using `&variable'.
I'm looking over at an example on: *this vs this in C++
The code is:
#include <iostream>
class Foo
{
public:
Foo()
{
this->value = 0;
}
Foo get_copy()
{
return *this;
}
Foo& get_copy_as_reference()
{
return *this;
}
Foo* get_pointer()
{
return this;
}
void increment()
{
this->value++;
}
void print_value()
{
std::cout << this->value << std::endl;
}
private:
int value;
};
int main()
{
Foo foo;
foo.increment();
foo.print_value();
foo.get_copy().increment();
foo.print_value();
foo.get_copy_as_reference().increment();
foo.print_value();
foo.get_pointer()->increment();
foo.print_value();
return 0;
}
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does. Why do I get an error if I removed the * from the Foo* functions while returning this not *this?
edit:
Also, why is:
foo.get_copy().increment();
foo.print_value();
yielding 1 not 2?
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does
Foo* get_pointer()
Foo* is a pointer that points to Foo object.
this is also a pointer that implicitly bind to the calling object of the member function. That's why the return type of those functions are Foo* not Foo.
The * is part of the type. So int means type int, and
int* type pointer to int. If the function returns pointer
to int, it is int* foo(), and if it retu rns a pointer to
Foo, it is Foo* Foo::get_pointer().
The definition reserves space for the defined object. A
declaration doesn't reserve any space, and definitions of things
that aren't objects (e.g. references or functions) don't reserve
any space either, at least not that you can see. (Obviously, a
function does exist somewhere in memory, and in many cases, the
compiler will need space as well for its implementation of a
reference. But they are invisible within the scope of C++.)
this, is always a pointer in C++, though you don't mention it explicitly anywhere. So while returning a this pointer, should use Foo*
this is actually an implicit object passed during function call, which is a pointer to the object which calls the function
It seems that you have changed the code from the example that you refer to so that get_copy() no longer returns a copy.
There are 2 ways of using * in your code example. One is for type declaration and the other is the dereferencing operator.
First the type declarations:
int *p means declaring p as a variable of type "pointer to an int".
Foo *get_pointer() means that the function get_pointer will return a value of type "pointer to a Foo object".
Now the dereferencing:
*p means "the value that p points to".
int a = 42;
int *p; // p is of type "pointer to an int"
p = &a; // set p to the address of a (p now "points to" a)
a = 117; // change the value of a
int x = *p; // set x to the value that p points to (which is a) - x will be 117
this is just a pointer to the object. *this means "the object that this points to". In your example this is of type Foo* (pointer to a Foo object) while *this is of type Foo (a Foo object).
"this" is a pointer.
you want to return a pointer to the instance (a specific allocated object).
Foo* get_pointer(){
return this;
}
or you want to return a pointer to the copy, allocate a new object.
//need to implement the copy here
Foo* get_copy(){
return this;
}
and not to the reference (address of the instance). this is why you need to return the pointer.
In ·std::unique_ptr· code in file "memory", I see operator overloading functions as
typename tr1::add_reference<_Ty>::type operator*() const
{
// return reference to object
return (*this->_Myptr);
}
pointer operator->() const
{
// return pointer to class object
return (&**this);
}
What does the &** mean in the second function? Thanks.
this is a pointer to the unique_ptr object.
*this is a reference to the unique_ptr object.
**this is dereferencing the unique_ptr using operator* (i.e. *this->_Myptr).
So, &**this is a pointer to the object pointed at by the unique_ptr (i.e. &(*this->_Myptr)).
As per the posted code, **this is invoking operator* overload which returns a reference to an object. so &**this becomes address of the returned object.
In other words, **this is same as (*this->_Myptr), and &**this is same as &(*this->_Myptr).
1st code:
#include <iostream>
using namespace std;
class demo
{
int a;
public:
demo():a(9){}
demo& fun()//return type isdemo&
{
return *this;
}
};
int main()
{
demo obj;
obj.fun();
return 0;
}
2nd code:
#include <iostream>
using namespace std;
class demo
{
int a;
public:
demo():a(9){}
demo fun()//return type is demo
{
return *this;
}
};
int main()
{
demo obj;
obj.fun();
return 0;
}
what is the difference between these two codes as both are working in gcc?i am new here so forgive me if my way of asking is wrong.
demo & fun() returns a reference to the current object. demo fun() returns a new object, made by copying the current object.
Both are valid but are different. In the first case demo& fun() a reference to the same object is returned, in the second case a new object is created. While both are the same, the semantics differ, run this example:
#include <iostream>
struct test {
int x;
test() : x() {}
test& foo() { return *this; }
test bar() { return *this; }
void set( int value ) { x = value; }
};
int main() {
test t;
t.foo().set( 10 ); // modifies t
t.bar().set( 5 ); // modifies a copy of t
std::cout << t.x << std::endl; // prints 10
}
Apart from what #Erik said about the return type, a little excursus on the this-pointer:
The following is equivalent:
struct my_struct{
my_struct* get_this() const { return this; }
};
my_struct obj;
my_struct* obj_this = ob.get_this();
std::cout << std::boolalpha; // to display true/false instead of 1/0
std::cout << "&obj == obj_this = " << &obj == obj_this << "\n";
The this pointer is just the pointer to that object, you can think of it as a hidden parameter. It's more understandable in the C way:
typedef struct my_struct{
int data;
// little fidgeting to simulate member functions in c
typedef void (*my_struct_funcptr)(struct my_struct*,int);
my_struct_funcptr func;
}my_struct;
// C++ does something similar to pass the this-pointer of the object
void my_struct_func(my_struct* this, int n){
this->data += n;
}
my_struct obj;
obj.data = 55;
// see comment in struct
obj.func = &my_struct_func;
obj.func(&obj, 15);
// ^^^^ - the compiler automatically does this for you in C++
std::cout << obj.data; // displays 70
Consider your function.
demo fun(){return *this;}
Here you are returning by value so one temporary object will be created which will be destroyed, once you assign the return value of fun to some other object.
While in case when you pass the reference, no object will be created newly, but it will pass actual object and even after assigning function return value object will not destroy till main object(used inside fun, in ur case its the object calling the function) won't go out of scope.
The concept you are trying to understand can be explained in more detail with other example.
consider function that is taking object as argument and returning object as argument.(also consider we have object that contains a pointer, we will assign value to pointer by first allocating memory to pointer and a destructor, which will free memory hold by pointer of object). Now when you return object as pass by value, temporary object will be created, that will have exact copy of main object(and temporary object's pointer will also point to same address or you can say holds the same address). Now inside main(), you assign/initialize any object with return value(object) of function. But when your temp object will be destroyed after assigning value, it will also free the memory because of destructor and when you try to fetch the same address value through assigned object(inside main() ) you will get error as that memory has been already freed.
But if you would have return value using reference, object returned by object won't destroy as main obj(inside function or through which we have called the function) is in scope and your pointer won't loose its memory. Making possible for assigned object to fetch address value through its pointer and avoid undesirable result.
In code 1 demo obj creates a fresh copy of demo. obj is initialised using demo's default constructor 'demo():a(9){}'. obj.fun() returns a reference to (already existing) obj.
In code 2 obj.fun() creates a new demo type object using demo's copy constructor (in your case it is compiler generated) and returns that copy to the caller.
Both code are valid.
1st code fun() is returning a reference to current object
2nd code fun() is returning the copy (by value) of the object
For 1st case, If you decide to return by value
then prefer to return a const
reference; i.e. const demo& fun();
and later you can copy it if needed.
Simply returning reference makes the
object modifiable, which may
accidently edit the content without
intent
For 2nd case, Do NOT return the object by value,
because it can create unnecessary
temporary copy which will effect
the memory/performance of your code