return by reference from copy assignment overload - c++

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.

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.

Reason why the operator= usually returns a reference to an object in C++?

So for example:
const Ball& operator=(const Ball& other)
{
// Irrelevant code
return *this;
}
So I have heard that you return a reference to an object because of cascading:
Ball a,b,c;
// Unimportant initializations
a=b=c;
But why can't the method be something like:
const Ball operator=(const Ball& other)
{
// Irrelevant code
return *this;
}
Or this:
const Ball* operator=(const Ball& other)
{
// Irrelevant code
return this;
}
What if I do something like:
Ball *a, *b, *c;
// Unimportant initializations
a = b;
Would this work with both the methods I provided?
I apologize if these are dumb questions. I am still fairly new at C++.
Any help would be nice.
The return type is convention, but normally it's Ball& not const Ball&. I think you can have anything there you like (void for instance, if you don't want to return anything at all). But it's best to have something that behaves like the assignment operator does with built in types. That way people won't be surprised how your assignment operator behaves.
This code
Ball *a, *b, *c;
// Unimportant initializations
a = b;
is just pointer assignment, it will always be legal but it has nothing to do with any assignment operator you define which is for Ball objects not Ball pointers.
Returning by value would work, but you make unnecessary copies.
Returning by pointer would prevent natural chaining, you'd need some weird thing like
a = *(b = c);
And
Ball *pa;
Ball *pb;
pa = pb;
will not use your user-defined assignment operator, the assignment operator for pointers is built-in and does pointer assignment.
If you have a const reference then you cannot assign to it. If you return a pointer, again, you assign the pointer value, not the object instance.
In most cases it makes sense to stick to what is called "int semantics" whereas you make your classes behave in the same manner int does. In particular, you want cascading to work.
If you have a reference, you can chain your operations, like this
a.add(b).subtract(c);
But if you return a pointer or const, you can not do that.
You can define it this way:
const Ball operator=(const Ball& other)
{
// Irrelevant code
return *this;
}
However, you will be returning a temporary copy. The compiler will likely fix this for you when it optimizes. Additionally, chaining a = b = c when operator= takes a const Ball&, you are passing a reference to a temporary.
Returning a pointer will not work as you cannot chain, and you are dealing with different data types (pointers on the left hand side, const references on the right).
This snippet is legal:
int a;
(a = 2)++;
In one statement, we assign 2 to a and then increment a. This means that a = 2 must evaluate to a reference to a.
In order to replicate this behavior with user made types, the assignment operator needs to return a reference.

Returning "this" pointer in a const function

I've been learning C++ and I am practicing with classes at the moment.
I created a class that stores a name and a score of a player and defines functions to
manipulate the data and show it.
One of the functions I created is to compare scores of two players and return a pointer
to the player with the higher score. This is the function:
Player * Player::highestScore(Player p2)const
{
if(p2.pScore>pScore)
{
return &p2;
}
else
{
return this;
}
}
From the main I create the following players:
Player p1("James Gosling",11);
Player *p4 = new Player("Bjarne Stroustrup",5);
I call the highestScore function:
Player *highestScore = p1.highestScore(*p4);
However as you may have noticed from reading the function itself, when I return the pointer to the object that called the method (if it has a higher score), I get an error that says:
return value type does not match the function type
This problem seems to disappear when I declare the return type of the function as a const, like this:
const Player * Player::highestScore(Player p2)const
The part that is confusing me is why does it allow me to return &p2, which is not const and doesn't allow me to return this, which is a pointer to the object that called the function, which isn't a const as well? Also even when I declare the function return type as a const, it still allows me to return &p2, even though the argument passed to the parameter is not a const Player object?
Sorry if the question seems strange or what I'm trying to do is very bad programming, but it's just for the purpose of learning by doing it.
The part that is confusing me is why does it allow me to return &p2, which is not const and doesn't allow me to return this, which is a pointer to the object that called the function, which isn't a const as well?
this is const (or, more accurately, is a pointer-to-const) in a const member function, just like all the data members:
#include <iostream>
#include <type_traits>
struct A
{
void foo()
{
std::cout << std::is_same<decltype(this), const A*>::value << '\n';
}
void bar() const
{
std::cout << std::is_same<decltype(this), const A*>::value << '\n';
}
};
int main()
{
A a;
a.foo();
a.bar();
}
Output:
0
1
Also even when I declare the function return type as a const, it still allows me to return &p2, even though the argument passed to the parameter is not a const Player object?
We can't see what you tried, but presumably it was Player* const, which is not the same as Player const* (or const Player*). You can add constness to &r2 just fine; taking constness away is a different story.
The difference between a const and non-const method is that in the first the this pointer in const and in the latter it is not. So when you try to return non-const pointer from a const function and return this, compiler complains, because there this is const and const-ness can not be automatically removed.
&p2 is simply a pointer to an argument and thus it is not const. Please keep in mind, though that &p2 is pointer to local variable and it is never safe to return that.
When you have a "const" function, you are pretty much promising that "We will not change the object instance in this call". The compiler makes this a const T* this for that type of function (where T is the type of your class, e.g Player).
Obviously, returning a pointer to something that is const as as a non-const pointer is a breach of the rule - because once some code has a non-const pointer to your object, the code can modify the object... Which breaks the promise that "this function won't modify".
So adding const to the return type from function is the right solution here.
You probably also want to change your code so that it takes a const *Player p2 as input - your current code returns a pointer to a local variable [it happens to be an argument, but it's the same principle - it doesn't exist when the function call has returned].
Edit: Unless you are actually returning a copy of something (e.g. an integer, string or a new structure allocated with for example new) in a function with const attribute, the return type should be const.

how does the ampersand(&) sign work in c++? [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.