Why can we assign to *this? - c++

In C++ ,whenever we call member function through an object ,it implicitly pass one argument to member function say classname * const this
eg :
void SetID(int nID) { m_nID = nID; }
becomes:
void SetID(Simple* const this, int nID) { this->m_nID = nID; }
So now in below example
#include <iostream>
using namespace std;
class Test {
private:
int x;
public:
Test(int x = 0) { this->x = x; }
void change(Test* t) { *this = *t; }
void print() { cout << "x = " << x << endl; }
};
int main() {
Test ctest1(10);
Test* ptest = new Test(20);
ctest1.change(ptest);
ctest1.display();
return 0;
}
So as we know internally ctest1.change will pass this pointer which is const (Test *const ptr). So how am i possible to change "this" to point to some other object . In abv example this now points to ptest
Also want to know what is difference between this and *this

So how am i possible to change "this" to point to some other object
You can't; it always points to the object on which the member function was called, and it can't be changed. As you say, it behaves (more or less) like an extra parameter of type Test * const - with the const meaning you can't change the pointer to point to anything else.
In abv example this now points to ptest
No it doesn't. *this = *t modifies the value of object that this points to, reassigning it with whatever t points to. It still points to the same object (with a new value) afterwards.
Also want to know what is difference between this and *this
this is a pointer to the object; *this dereferences the pointer to access the object itself.

It calls the assignment operator. You are not changing this to point to a different object, you are changing the memory that this is pointing to.

How can I change this to point to something else??
In plain English :: You couldn't do it and you shouldn't do it.
Reason is "this" for class X is "X *const this".

Related

I don't understand what's the different between a '&' in and out of a class object's variable parentheses [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (&param == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy &param) is called:
b->isitme(a);
A test is evaluated inside this method:
if (&param == this) // do something
Here's the tricky part. param is an object of type CDummy, but &param is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.

Using Variable When Declaring Constructors [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (&param == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy &param) is called:
b->isitme(a);
A test is evaluated inside this method:
if (&param == this) // do something
Here's the tricky part. param is an object of type CDummy, but &param is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.

C++ pass by reference and this object

Why is answer "OK"?
class CTest {
public:
int isitme(CTest& cobj);
};
int CTest::isitme(CTest &cobj)
{
if(&cobj == this)
{
return true;
}
else
{
return false;
}
}
int main()
{
CTest a;
CTest *b = &a;
if(b->isitme(a))
{
cout<<"OK";
}else
{
cout<<"not OK";
}
return 0;
}
Because a member function implicitly receives as an argument a pointer to the object it is invoked on. This pointer is made available within the body of the function as the this pointer.
So when you do:
b->isitme(a)
The member function isitme() implicitly receives the pointer b as an argument, and that pointer will be seen as the this pointer inside the function.
Since b points to a, this will point to a (after all, you are invoking the member function isitme() on object a through the pointer b).
Since a is what is being passed as an explicit argument, a is also what the reference cobj is bound to. Therefore, taking the address of cobj gives you the address of a. Which in turns mean, that the expression:
// Address of "a": "cobj" is bound to argument "a" in the function call
// vvvvv
&cobj == this
// ^^^^
// Address of "a": the function is called through a pointer to "a"
Evaluates to true.
The short answer is that b is a pointer to a -- they both refer to the same actual object, so when you compare those "two" objects' addresses, they compare equal.
There's something else that really needs to be pointed out, and although it's more comment than answer, it won't fit in a comment, so...
int CTest::isitme(CTest &cobj)
{
if(&cobj == this)
{
return true;
}
else
{
return false;
}
}
This is, quite honestly, pretty lousy code. Since it's really returning a bool, you should declare it to return a bool. It's also much better to directly return the result from the comparison. You should also do some reading about "const correctness". Taking those factors into account, your function ends up looking more like this:
bool CTest::isitme(CTest const &cobj) const {
return this == &cobj;
}
There are a couple of things going on here.
First, there is only one copy of CTest being allocated. To check this, you could put a print in the constructor:
class CTest {
public:
CTest() {
cout << "Constructor called";
}
...
};
If you then invoked your program, you'd see that the constructor was called only once.
When isitme is invoked, the this pointer is being compared to the address of the cobj parameter. Both are pointing to the same object, so they both contain the same memory address. Thus, the comparison passes.
The other thing to notice is that you are passing by reference. If you didn't pass by reference, then this would not work. For example, if you had the following code:
class CTest {
public:
...
bool isitme(CTest cobj) {
return this == &cobj;
}
};
Then the object would be passed by value. As a result, a copy of cobj is made. In fact, another constructor (the compiler provided default copy constructor) is called to make a new object which is a copy of the given one.
To prove this, override the default copy constructor to display a message.
class CTest {
public:
// Default constructor
CTest() {
cout << "Constructor called" << endl;
}
// Copy constructor
CTest(CTest& source) {
cout << "Copy constructor called" << endl;
}
// Comparison
bool isitme(CTest obj) {
return (this == &obj);
}
};
// Main program
int main (int argc, char* argv[]) {
...
CTest a;
CTest* b = &a;
cout << (b->isitme(a)) << endl;
...
}
Now if you run the program, you'd notice both constructors are called. The first time is during the constructor for a. The second time is when you pass a to the isitme method and it creates a copy.
When passed by value, the isitme check would fail because it is comparing the pointers (memory addresses) of two different objects.
int CTest::isitme(CTest &cobj)
{
// cobj is a reference, but still an object
CTest * pCobj = &cobj; //pCobj is now the pointer to the actual memory
//so it's the same as this pointer. Because you did before CTest *b = &a;
}
b is pointing a, then you are using a in
b->isitme(a)
the isitme() simply checks the object passed as parameter against this. In this case it is, so OK

C++ pointer and address clarification in relation to the current object

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.

function returning this pointer in c++

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