I have this snippet of the code
Stack& Stack:: operator=(const Stack& stack){
if(this == &stack){
return *this
}
}
here I define operator = but I can't understand, if I receive by reference stack why it should be & in this == &stack and not this == stack and why we return * in return *this and not this thanks in advance for any help
Because this is a pointer (i.e. of type Stack*), not a reference (i.e. not of type Stack&).
We use if(this == &stack) just to ensure the statement
s = s;
can be handled correctly (especially when you need to delete something in the old object). The pointer comparison is true only when both are the same object. Of course, we could compare by value too
if (*this == stack)
return *this;
else {
...
}
But the == operation can be very slow. For example, if your stack has N items, *this == stack will take N steps. As the assignment itself only takes N steps, this will double the effort for nothing.
stack is of type Stack&, and this is of type Stack*. You're checking if the address of stack is equal to this.
Short answer to your two questions.
As I understand you ask why we use & sign if we get reference as a function parameter(not an abject). Because reference to an abject is not address of it. You should use operator&() in order to get the address of an object.
this is a pointer, but you should return reference thus you return *this
if I receive by reference stack why it should be & in this == &stack
Because this is a pointer (or "address") and stack is a reference (not a pointer): so you need to say &stack (which means "address of stack"), so that its type matches the type of this.
why we return * in return *this and not this
Because this is a pointer (not a reference), but the method is supposed to return a reference (not a pointer), so you need to deference it in order to turn the pointer into a reference.
Related
I am new to C++. I need some help understanding this code snippet.
Queue & operator=(const Queue &rhs)
{
front = rhs.front;
nWaiting = rhs.nWaiting;
for (int i = front, j = 0; j < nWaiting; j++)
{
elements[i] = rhs.elements[i];
i = (i + 1) % 100;
}
return *this;
}
I am unable to understand why there is an '&' before operator in the code and how does this work along with *this.
I understand operator overloading. For eg. the code below for addition operation overloading. However I don't understand why '&' is required for assignment operator (=) overloading.
V3 operator* (const double factor, const V3 &b)
{
return (b * factor);
}
The reference means that avoid copying the object. As a result, it will return a reference to the same object. Moreover, it will provide lvalue as a result. And if you think about it, that's what you want to happen when the assignment operator is used.
Every object in C++ has access to its own address through this pointer.
That means that the you return the object itself.
If your question is why we use *this instead of this, then this happens because you need to dereference the pointer first, since the return type is a reference (and not a pointer for example).
The & means the operator returns a reference (the original object), instead of a value (a copy of the object). This avoids unnecessary copying. this is a pointer to the object itself which the operator is called on, so return *this means return a reference to the object on the left side of the =.
This allows for the operator to be chained, like a = b = 1. This assigns 1 to b first, and a reference to b is returned. The value of b then gets assigned to a. So a and b both are 1.
The operator could be fine without any return value, however it is common to enable chaining as in
c = (a = b);
This will assign b to a and then assign the return value of the operator= call to c. As you dont want to make a unneccesary copy you return a reference to the object itself aka *this. Actually avoiding a copy is not the only reason for using a reference, but if you consider
(d = e) = f;
then this will only work as expected (first assigning e to d and then assigning f to d) if operator= returns a non-const (!) reference.
Note that operator* is different, because it is not supposed to modify the object it is invoked on but rather it returns a new instance (hence no & in the return of operator*).
I've seen many tutorials and tried to find the answer on stackoverflow but with no success.
What I'm not sure of is; is there some praxis when to return by value or by reference, when overloading an operator?
For e.g.
Class &operator+(){
Class obj;
//...
return obj;
}
or the same thing but by value
Class operator+(){
Class obj;
//...
return obj;
}
And I'd like to mention, I've noticed that in almost 90% of cases when returning the same object (*this), is being referenced on the same object returned. Could someone explain why is that so, as well?
The first option of returning from operator+ by by reference is wrong, because you are returning local object by reference, but the local object ceases to exist after the operator function body ends. Generally:
Mutating operators like += or -= return by reference, because they return the mutated object itself (by: return *this;)
Normal operators like + or - should return by value, because a new object needs to be constructed to hold the result.
... is there some praxis when to return by value or by reference, when overloading operator?
Yes, there are some canonical forms found here. They don't all have the same form - they vary by operator. The general advice is to follow the semantics of the built-in types. As with all functions, general rules still apply, such as not returning references to local variables (as shown in the OP).
E.g. (found in the link above) given the addition operator of the question;
class X
{
public:
X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
{ // but often is, to modify the private members)
/* addition of rhs to *this takes place here */
return *this; // return the result by reference
}
// friends defined inside class body are inline and are hidden from non-ADL lookup
friend X operator+(X lhs, // passing lhs by value helps optimize chained a+b+c
const X& rhs) // otherwise, both parameters may be const references
{
lhs += rhs; // reuse compound assignment
return lhs; // return the result by value (uses move constructor)
}
};
The operator+ is a non-member method (often as a friend) and returns by value - this corresponds to the semantics of the built in types. Similarly, the operator+= is a member method and returns by reference (an updated version of *this).
... when returning the same object (*this), is being referenced on the same object returned. Could someone explain why is that so, as well?
If the return type is by-value (X operator+), then return *this; means that a copy of the current object (what is pointed to by this) is made and returned.
If the return type is by-reference (X& operator+), then return *this; means that a reference to the current object (what is pointed to by this) is returned (i.e. not a copy).
MyObject& MyObject::operator++(int)
{
MyObject e;
e.setVector(this->vector);
...
return &e;
}
invalid initialization of non-const reference of type 'MyObject&' from an rvalue of type 'MyObject*'
return &e;
^
I am not sure what it's saying. Is it saying that e is a pointer, because it's not a pointer. Also, if you'd make a pointer to the address of e, it would get wiped out at the end of the bracket and the pointer would be lost.
Your return type is MyObject&, a reference to a (non-temporary) MyObject object. However, your return expression has a type of MyObject*, because you are getting the address of e.
return &e;
^
Still, your operator++, which is a postfix increment operator due to the dummy int argument, is poorly defined. In accordance to https://stackoverflow.com/a/4421719/1619294, it should be defined more or less as
MyObject MyObject::operator++(int)
{
MyObject e;
e.setVector(this->vector);
...
return e;
}
without the reference in the return type.
You're correct that e is not a pointer, but &e very much is a pointer.
I'm reasonably certain that returning a reference to a stack variable that will be out of scope before you can use it is also not such a good idea.
The general way to implement postfix operator++ is to save the current value to return it, and modify *this with the prefix variant, such as:
Type& Type::operator++ () { // ++x
this->addOne(); // whatever you need to do to increment
return *this;
}
Type Type::operator++ (int) { // x++
Type retval (*this);
++(*this);
return retval;
}
Especially note the fact that the prefix variant returns a reference to the current object (after incrementing) while the postfix variant returns a non-reference copy of the original object (before incrementing).
That's covered in the C++ standard. In C++11 13.6 Built-in operators /3:
For every pair (T, VQ), where T is an arithmetic type, and VQ is either volatile or empty, there exist candidate operator functions of the form:
VQ T & operator++(VQ T &);
T operator++(VQ T &, int);
If, for some reason, you can't use the constructor to copy the object, you can still do it the way you have it (creating a local e and setting its vector) - you just have to ensure you return e (technically a copy of e) rather than &e.
Change return &e; to return e;. In the same way that a function like
void Func(int &a);
isn't called with Func(&some_int) you don't need the & in the return statement. &e takes the location of e and is of type MyObject*.
Also note, MyObject& is a reference to the object, not a copy. You are returning a reference to e, which will be destroyed when the function finishes and as such will be invalid when you next make use of it.
My question refers to pointers with classes and the keyword this.
class class1 {
public:
bool isitme(class1& temp){
if(this == &temp)
return true;
else return false;
}
};
int main () {
class1 c3;
class1* c2 = &c3;
if(c3.isitme(*c2))
cout << "c3 == c2"; //it is returning that
system("pause");
}
The code above is working, but what I do not understand is why it works only when bool isitme(class1& temp) and if(this == &temp) are in the same function isitme().
I mean, we already read the block of memory class1& temp of temp in the class parameters and should be able to compare that block of memory with the keyword this. Why is the function only true when I double get the reference (this == &temp)?
Thanks
this is a pointer, whereas temp is a reference. When you write &temp in your if statement, you are taking the address of temp. This converts it to a pointer that can then be compared to this.
Do not confuse reference declarations with use of the address-of operator. When & identifier is preceded by a type, such as int or char, then identifier is declared as a reference to the type. When & identifier is not preceded by a type, the usage is that of the address-of operator.
Taken from: http://msdn.microsoft.com/en-us/library/w7049scy(v=vs.71).aspx
It's been a while since c/c++ days, but let me take a stab at this...
You're not using the reference operator twice. When you specify class1& you're only specifying the type of the parameter (the type is "reference of type class1"), not actually doing anything to temp. Later you actually dereference the parameter with &temp. It's only the second appearance of the ampersand that actually is a reference operator.
The & operator within the method declaration simply means that the object passed should not be copied, but rather point to the same location as the object passed to it (it's a reference). The & operator in if(this == &temp) is needed to actually get the address of that object (a pointer) so that you can compare it to the this pointer.
The reference "operator" in the signature of the isitme method denotes a reference, that is, an alias for the object itself.
On the other hand, in the line if(this == &temp), the operator is used directly on the object and thus returns the address of the object (a pointer to it).
So, if you want to check if the entered reference is equal to this, you need to compare to a pointer, which is exactly what the referance operator returns.
& in the class parameter list means the object is passed by-reference. That is, temp is an alias for the class1 object. &temp is simply taking the address of that object and comparing it to the object pointed to by this. The two syntaxes are semantically different, you're not taking the address twice.
this is an assignment operator. &rhs != this is confusing. my questions: rhs is a reference of Message type. What does &rhs mean? what does & do (a memory address of a reference?)?
Another question is about return *this . since we want a reference to type Message, but *this is a Message typed object, right? How can we return an object to a reference?
Message& Message::operator=(const Message &rhs)
{
if (&rhs != this)
{
some functions;
}
return *this;
}
&rhs means address of the object which reference is referecing to.
Message a;
const Message &rhs = a;
if (&rhs == &a) std::cout << "true" << std::endl;
This is will print true.
A reference is not a different object; it is just a syntactic sugar of pointer, which points to the same object whose reference it is. So when you write return this, it returns a pointer to the object, but if you write return *this, it returns either a copy of the object, or reference to the object, depending on the return type. If the return type is Message &, then you tell the compiler that "don't make a copy and instead return the same object". Now the same object is nothing but a reference. A reference of an object can be made anytime. For example, see the declaration of rhs above; it is const Message & rhs = a, since the targer type is mentioned as reference type, you're making a reference rhs of the object a. It is that simple.
Besides Nawaz's great answer, I want to point out that you have to be careful about returning a reference to a local variable which will go out of scope after function return. So avoid returning a reference like this:
string& foo()
{
string result = "abc";
return result;
}
which causes the following compiler warning:
reference to local variable result returned
A reference is just an alias to an object. References are formed by request of the function that is called; they are not (necessarily) part of an object's type. This is probably already familiar to you, but consider this:
void f1(int a) { ++a; }
void f2(int & a { ++a; }
int main()
{
int x = 5;
f1(x);
f2(x);
}
Surely you know the difference between the two functions. But note that x is always just an object of type int. Whether it is passed by reference or by value is not a property of x, but rather of the function.
The same goes for return types:
int q;
int g1() { return q; }
int & g2() { return q; }
int main()
{
++g2();
++g1(); // error
}
Again, q is just an object. Whether return q; returns it by value or by reference is not a property of q, but of the function. g1 makes a copy of q, while g2 returns a reference to the actual q object (which we can increment). (The return value of g1 cannot be incremented, precisely because it doesn't have a permanent existence and this would be meaningless (technially, the expression is an rvalue).)
So in you example, return *this; returns a reference to the object itself. That has nothing to do with this, but it has everything to do with the fact that the return type of the function is Message&.