Click here to Skip to main content
15,030,954 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
#include <iostream>
using namespace std;

class Time {
private:
	int hours;             // 0 to 23
	int minutes;           // 0 to 59
public:
	// required constructors
	Time(){
		hours = 0;
		minutes = 0;
	}
	Time(int h, int m){
		hours = h;
		minutes = m;
	}
	// method to display time
	void displayTime() {
		cout << "H: " << hours << " M:" << minutes << endl;
	}

	Time& operator++()
	{
		++minutes;
		if (minutes>=60)
		{
			++hours;
			minutes = minutes - 60;
		}
		return *this;
	}

	Time& Time::operator++(int){
		
		Time temp(hours, minutes);
		minutes++;
		if (minutes >= 60)
		{
			hours++;
			minutes = minutes - 60;
		}
		return *this;
	}
	
};

int main() {
	Time T1(11, 59), T2(10, 40);

	T2 = ++(++T1); // 
	T1.displayTime();        // display 12,01 ok
	T2.displayTime();        // display 12,01 ok

	T2 = (T1++)++;           
	T1.displayTime();        // display 12,03 οκ
	T2.displayTime();        // display 12,03 why?? i think it must be 12,01

	return 0;
}


What I have tried:

The problem is at the object T2
Posted
Updated 1-Feb-17 3:08am
Comments
Philippe Mori 1-Feb-17 9:17am
   
You should almost always follows predefined operator signatures when you overload an operator. Postfix operator should be declared as Time operator++(int). It is always a good idea to read the documentation before writing code instead of guessing and then wondering why the code does not works.
Philippe Mori 1-Feb-17 9:21am
   
By the way, in my opinion it is not a good idea to overload ++ operator in this case as it might not be obvious that the increment if 1 minute. What if at some point, you decide that Time should have a resolution of 1 second. It is better to be explicit and it will make your code easier to maintain.
Philippe Mori 1-Feb-17 9:24am
   
Also your comments about the displayed values does not match the actual code. Your code would display H:12M:1. If you take the time to write what the code output, at least make the effort to match the actual output. 

It is correct by your code:
C++
T2 = ++(++T1);

1. you increment the T1 in the braces
2. you increment the T1 outside the braces
3. you assign the T1 values to T2

tip: use a debugger to step into the three function calls of this code line.
   
Comments
Member 12975649 31-Jan-17 8:07am
   
@KarstenK But i want the double postfix ++ not the prefix! thanks
Your implementation of the postfix operator is wrong. You must return temp (the unchanged object) instead of the modified object:
Time operator++(int)
{
    Time temp(hours, minutes);
    minutes++;
    if (minutes >= 60)
    {
        hours++;
        minutes = minutes - 60;
    }
    // Return unchanged object here!
    return temp;
}

See also Increment and Decrement Operator Overloading (C++)[^].
That uses the prefix increment within the postfix implementation:
Time operator++(int)
{
    Time temp = *this;
    *++this;
    return temp;
}
   
v2
Comments
Philippe Mori 1-Feb-17 8:58am
   
But you should also returns the time by value in that case.
Jochen Arndt 1-Feb-17 9:27am
   
Thank you for the correction.
Philippe Mori 1-Feb-17 9:33am
   
So fix your code by removing the reference: Time operator++(int).
Since you are overriding both operators the normal ordering rules do not apply. The right-hand side of each expression will be completely evaluated before the result is passed to the left-hand side. Stepping through the code with your debugger will show you what happens.
   
Comments
Member 12975649 31-Jan-17 8:10am
   
@Richard MacCutchan T2 = (T1++)++; can u tell me what actions step by step are happening?
Richard MacCutchan 31-Jan-17 8:13am
   
You can do it for yourself by stepping through the code with your debugger. as I already suggested.
Member 12975649 31-Jan-17 8:15am
   
thanks for your help man!
Richard MacCutchan 31-Jan-17 8:18am
   
Philippe Mori 1-Feb-17 9:25am
   
As far as I know, the fact that a user defined operator is used have no impact on the expression evaluation order. The main problem is that the postfix operator is incorrectly defined and thus does not provided the intended behavior.

I think the only operators for which user defined operator change how the expression is evaluated are && and || as short-circuit evaluation does not works in that case as both side need to be evaluated before calling the operator function.

For any other operators, the main problematic case is when the same variable is used multiple time in an expression in which there are no sequence point... Same kind of problem could occurs with user defined functions.
Richard MacCutchan 1-Feb-17 9:29am
   
The actual problem is that the overloaded operator was returning the final value of the variable, rather than the initial value. And using a double increment in a single expression is never a good idea, even with parentheses.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900