Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am new in C++ and I've got some questions. I saw operator ++ overloading at complex numbers and I cant understand:
Why I create a tmp variable
why my first operator is Complex & and second it's just Complex
Why return *this;(i know cause of Complex& but why)
if i used Complex without & what would happened?(i run it and its the same result)
Don't look at comments it's Greek :)
Complex & Complex::operator ++(){
r=r+1;
return *this;//to this einai to pointer tou trexontos alla 8eloume dereference ara vazoume *this gia na epistrepsoume refernce//
}
Complex Complex::operator ++(int ){
Complex tmp(*this);
operator ++();
return tmp;//ftiaxnoume ena tmp tou antikimenou pou exoume meta efarmozoume to operator++ kai epistrefoume to tmp//
}
the different signature (Complex& vs Complex) is because these operations i++ and ++i do different things. One returns a copy of the old value (the second one) by value, the first one returns a reference to the actual value if x - by reference
The tmp variable is needed because you need to return the old value after incrementing the value (thats what x++ does)
you need to return a reference to the current object - so return *this - this is a pointer to the current object; *this is the object
2 - Complex & returns a reference to the same object, Complex returns a copy of it.
1 - that is why a temp variable is created, in order to increment the actual object but return the copy, in order to simulate the "use and then increment" postfix operator.
3 - because while i++ returns a copy of i (and increments i), ++i returns i incremented.
4 - the operator will return a copy of the incremented object, not the actual incremented object.
With a variable x, you can write ++x or x++. Former will do a ++, and if it is part of a bigger expression, use the new x. Latter will do the ++ too, but uses the old x for the current expression (it´s like the ++ comes a line after the current one).
If you overload ++, you need to separate if it is prefixed or suffixed.
It looks somewhat strange, but if you mean the suffixed version, you need to have a nameless int as parameter of the function (nothing for prefix). There is no meaningful value passed or something,
it´s just to make a difference between the two possibilites.
So, in the suffix variant, you´ll have a temporary copy to keep
the old value while you´re doing the ++ (ant return the old value for this one time).
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
i am writing since i would like to understand something about the design of C++.
The question is the following: in C++ it is possible to overload a class operator by passing two rhs values. however there is no way to obtain information about the
output to which these operations are applied.
think for example to the implementation of a Matrix class:
the relevant code would look something like
template <typename DataType, int NumberOfRows, int NumberOfColumns>
class Matrix
{
DataType _data[NumberOfRows * NumberOfColumns];
public:
typedef DataType TDataType;
Matrix() {}
...missing code...
template <int SecondNumberOfColumns>
friend inline Matrix<DataType, NumberOfRows, SecondNumberOfColumns>
operator*(Matrix const& First,
Matrix<DataType, NumberOfColumns, SecondNumberOfColumns> const& Second)
{
Matrix<DataType, NumberOfRows, SecondNumberOfColumns> result; //HERE THE ALLOCATION OF A TEMP IS NEEDED
for (int i = 0; i < NumberOfRows; i++)
for (int j = 0; j < SecondNumberOfColumns; j++) {
DataType temp = DataType();
for (int k = 0; k < NumberOfColumns; k++)
temp += First(i, k) * Second(k, j);
result(i, j) = temp;
}
return result;
}
}
the * operator needs to allocate a temporary, implying that if one wants to do an operation like A = B*C either has to hope for compiler optimizations or go for techniques such as expression templates.
I would like to understand what is THE DEEP REASON for which the design of C++ did not include the possibility of writing something like
operator*(
ReturnType& out, <---- THIS WOULD BE THE RETURN
Type1& input1,
Type2& input2
)
{...}
in which the "out" is passed explicitly when passing the operator (the point is that such a syntax should still map to the user writing
out = input1*input2)
I am asking my question since this would greatly ease writing a lot of libraries, and i guess the solution was considered and discarded. I would love a didactic explanation of why this option was not admitted
thank you in advance
Riccardo
I would like to understand what is THE DEEP REASON for which the design of C++ did not include the possibility of writing something like in which the "out" is passed explicitly when passing the operator (the point is that such a syntax should still map to the user writing out = input1*input2)
That mapping is the problematic part. It presupposes that out is an object which already exists. So obviously code like auto out = input1*input2; would be impossible, since out does not exist as an object until the operator* finishes execution.
And what if the default constructor value initializes the object? There's no reason to pay that cost if you're just going to overwrite the object. Better to let operator* create the object for you than for you to create an "empty" one.
And that doesn't even consider types that don't allow default construction or otherwise "empty" states at all.
More importantly, it would make simple statements like out = input1*input2*input3 impossible. This manifests at least one temporary object during its evaluation. In your model, where does that temporary object come from? In the regular C++ model, it's the return value.
Or in more rigorous C++17 speak, the prvalue returned from the first operator* will be used to manifest a temporary object, which is used as the argument for the second operator* call. This is no different from any other function which returns a prvalue.
At the end of the day, C++ is predominantly a value-oriented language. Expressions of multiple parameters resolve to a single value; that's the standard way things work. Sure, you can create the effect of an output value via a reference/pointer parameter. But that is generally not the way the language wants to work. It may sometimes be necessary, but you generally want to compute values.
And operators are among the part of C++ that is most value-oriented. a + b * c produces a single value. This ought to be able to initialize an object (auto x = a + b * c;) or work on an existing object (x = a + b * c;). It should not require that the return value already exist; that's an implementation detail, not an interface requirement.
How would you call an operator that took 3 inputs like you suggested? The only way I can think of calling it would be to use the verbose operator syntax:
m.operator*(out, in1, in2);
But if you're going to do that, you might as well just write an ordinary, named member function and be done with it.
Overloading operators is in large part designed to make natural syntax for math expressions with value-type objects that behave in ways consistent with numbers. What you want is not natural syntax for using an operator, and would only complicate the language with little/no tangible benefit.
Just started doing operator overloads and my teacher didn't go too in depth into them so I was wondering why the return type is different for Prefix/Postfix increment/decrement. When I see the prefix overloads the return type is written as Type&, but the return type for the postfix is written as Type. I made the prefix without the & and the functions both ran properly. Does the return type affect anything or is it just another way to distinguish prefix from postfix?
The reason is to allow chaining:
++ ++ ++ i;
To allow i to triple increment, ++ must return the reference and take the reference. If it returns a temporary copy, the second ++ would increment ... the temporary copy (in fact, a temporary copy won't bind a &, so it will not even compile).
To add to Emilio's answer postfix incrementing creates a temporary variable and sets that to 1 plus the variable you want to increment where as prefix incrementing increments the actual variable which can have a performance boost in certain cases.
Main reason is to follow semantics for builtin types in C++ where prefix increment/decrement returns lvalue and postfix one returns rvalue. Details can be found here
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have just learned that the result of the prefix increment operator in C++ is an lvalue. There are probably cases where this behavior helps the programmer be more effective, but I could not think of any. What are some idiomatic uses of this behavior of the prefix increment operator?
The reason prefix ++ returns an lvalue is orthogonality; I've not seen
any use for it that wouldn't qualify as obfuscation. But the question
is: what rules apply to cause an expression to be an lvalue. In C, the
basic rule is that expressions which modify one of their operands aren't
lvalues, but a number of people wanted to support things like:
T&
someFunction( T& lhs, T const& rhs )
{
// ...
return lhs = rhs;
}
This works for user defined types (because operator= will be a member
function), and some members wanted to support it for built-in types as
well. So the basic rule became: if an operator required an lvalue
operand, which it modified, and the results of the operator were the
changed operand, then it is an lvalue. (Thus, while prefix ++ is an
lvalue, postfix isn't, because the results of the expression aren't the
changed operand.)
Personally, I'm not sure I agree. I have no problem with replacing the
above with:
T&
someFunction( T& lhs, T const& rhs )
{
// ...
lhs = rhs;
return lhs;
}
which is how I'd write it in my own code. But given that the first
example is legal for user defined types (where operator= returns
a T&), and that a number of committee members did like it, it seems
logical to extend it to the built-in types, and the resulting rule is
coherent, even if no one ever actually has the occasion to use the
results of prefix ++ as an lvalue.
EDIT:
Just to make it clear: I asked this very question at one of the
meetings (when we were defining C++ 98), and this was the
response I got (from, if I recall correctly, Andy Koenig, who
worked with Stroustrup on the earliest implementations of C++).
It was also the justification for having the default
implementation of operator= return a T& rather than a
T const&.
The change from C where ++x is an rvalue to C++ where ++x for built-in types is an lvalue is probably because there are much more useful applications. For example, you might define a function alternatively as
void f (int x);
void f (int& x);
and the fact that ++x is an lvalue allows you to call f (++x); in either case. In C, only the first case was legal, and works just fine with an rvalue. In C++, you want an lvalue.
i=9;
j=10;
k = ((i)>(j))?(j):(++i);
In the above case we have a use of prefix increment operator as you can c we first check i>j which will be false in this case then we are assigning the value ++i to k which will give us k=1.
Here in one single statement we have used i twice but once the value was 9 and other time the value was 10.
If you try to achieve this without prefix increment operator we would have to use another temporary variable to store to the value of i then increment i to assign to k.
Without using prefix operator
i=9;
j=10;
Temp=i;
i=i+1;
k = ((Temp)>(j))?(j):(i);
Still if we arrive at a conditin where temp is greter than j then we will have the value of i incremented even if we dont use it. Using prefix operator tje value of i will only increment if i less than j.
This question already has answers here:
Overloading ++ for both pre and post increment
(4 answers)
Closed 9 years ago.
I have these code of lines from a program my teacher made :
TimeKeeper& operator++() {
d_seconds++;
return *this;
}
const TimeKeeper operator++(int) {
TimeKeeper tk(*this);
++(*this);
return tk;
}
And one of the questions my teacher asked us was "operator++() returns a reference and operator++ (int) returns a value, explain why?"
Can anyone explain this to me??
If you need the rest of the code i dont mind putting it on!
Thanks!!
The one without an extra int is the preincrement operator while the one with the extra int parameter is the post increment operator. This somewhat awkward notation is somewhat of a hack to distinguish the two notations and the int can't be used for any useful purpose:
TimeKeeper keeper;
++keeper; // pre increment: calls TimeKeeper::operator++()
keeper++; // post increment: calls TimeKeeper::operator++(int)
The difference between pre increment and post increment is that for pre increment the value of the expression is that after the increment while for post increment it is the value before the expression. For post increment the object the increment is applied to gets moved forward and a different object representing the state before the increment is returned. The object representing the previous state is a temporary object which only lives within the expression and which, thus, needs to be returned by value. For the pre increment only one value is involved and that can be returned immediately by reference.
In the above snippet the result from keeper++ isn't used: you should only ever use the post increment operator when using its result. Otherwise it will just waste creating a temporary object pretty much along the lines of your teacher's code which is then thrown away. Even if the construction is cheap, it may waste a couple of CPU cycles. The same overloading and reasoning for not using it unless necessary applies to the decrement operator operator--(). Oddly enough, C++ is thus not idiomatic C++!
operator++() is the preincrement operator (++x), while operator++(int) is the post increment operator (x++). If you understand how these operations work, then you should be able to explain why one of them must return a copy.
Take a simple example:
int x = 1;
std::cout << x++ << "\n"; // prints 1
std::cout << ++x << "\n"; // prints 3
What happened to 2?
The value of x became 2 in the x++ expression, 1 was printed (the value of x prior to the increment operation).
In the second statement, the value of x becomes 3 in the ++x expression.
To distinguish these two operators there must be some syntaxical difference. So to distinguish postincrement operator from preincrement operator a parameter of type int that is not used was added to declaration of postincrement operator.
The preincrement operator returns the object itself. It is why its return type a refernce. The postincrement operator returns a temporary object and increment the original object. it is way it returns a value.
In C++, if you have a for loop that "copies" objects of a user defined type using a move constructor, does it make any difference if you use ++i or i++ as the loop counter?
I know this question seems rather vague, but I was (I believe) asked this in a phone interview. I wasn't sure if I understood the question correctly, and the interviewer took this as my not knowing the answer, and cut the interview short.
What could he have been getting at?
In C++, if you have a for loop that "copies" objects of a user defined type using a move constructor [...]
First of all, a move constructor is used for move-constructing, which usually means you are not "copying": you can realize moving as copying - in fact, a class which is copy-constructible is also move-constructible - but then why defining a move constructor explicitly?
[...] does it make any difference if you use ++i or i++ as the loop counter?
It depends on what i is. If it is a scalar object, like an int, then there is no difference at all.
If i is a class-type iterator, on the other hand, ++i should be more efficient (on a purely theoretical ground), because the implementation of operator ++ will not have to create a copy of the iterator to be returned before the iterator itself is incremented.
Here, for instance, is how stdlibc++ defines the increment operators for the iterator type of an std::list:
_Self&
operator++()
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
As you can see, the postfix version (the one accepting a dummy int) has more work to do: it needs to create a copy of the original iterator to be refurned, then alter the iterator's internal pointer, then return the copy.
On the other hand, the prefix version just has to alter the internal pointer and return (a reference to) itself.
However, please keep in mind that when performance is concerned, all assumptions have to be backed up by measurement. In this case, I do not expect any sensible difference between these two functions.