You are here:

C++/any idea pls

Advertisement


Question
QUESTION: Hello,

i was studying the post increment and preincrement operator overloading in the c++ language.

I have written this pre increment code to increment a counter, now i want to use it to increment  the time as the user enters the time. what i need now is this, i want the user to enter the time in hrs and min like : 12:40 and then the time is incremented to 12:41. below is the code but i want to only modify the post and pre increment operator i have written. here there is a private variable called count but if there could be any way i could increment the time, which is a pointer, it would do the magic. that is in the post and pre increment methods, use the getTmin() to convert first the time to minutes , increment or decrement it and then reconvert it back. any small code, or direct idea will do,

code :


#include<iostream>
using namespace std;


class Time {
 
  public:
  Time(int _hr, int _min) : hr( _hr ) { min = _min; };
  Time(int _asMin=0 ) { hr = _asMin/60; min = _asMin%60; };

 
  friend ostream &operator<<(ostream &out, const Time &t2);
   friend istream &operator>>(istream &in, Time &t2);
   Time operator++(int); //post increment
   Time&operator++();  //pre increment
   int getTmin(){return hr*60 + min;}
   void setHr(int h);
  void setMin(int m);
 
  private:
  int min;
  int hr;
 int count;
  };
  
  Time Time:: operator++(int)
  {
       Time old = *this;
       count++;
       return old;
       }
  Time& Time :: operator++()
  {
    ++count;
    return *this;
    }
  ostream &operator<<(ostream &out, const Time &t2)
        {
         out << t2.hr<< endl;
         out << t2.min << endl;
         return out;
        }
        
istream &operator>>(istream &in,  Time &t2)
{
       in >> t2.hr;
       in >> t2.min;
       return in;
       }
int main(void)
    {
      Time time;
        cout << "Enter time :"<<endl;
         cin >> time;
         cout << time++ << endl;
      cout << ++time << endl;
  }





ANSWER: before we come to the prefix and postfix increment operators, a few issues first:

a constructor should ensure that the object is initialized to a valid state. for example, if someone tries to initialize a time in the following way Time atime( -345, 12345 ) ;
the constructor should either fail (throw) or correct the values silently.

unless your design intent is to provide an implicit conversion via the constructor, you should declare single argument constructors as explicit.
see: http://weblogs.asp.net/kennykerr/archive/2004/08/31/Explicit-Constructors.aspx

a stream extraction operator should check for incorrect input. if the input is incorrect, it should
a. leave the object in its previous state (ie. not modify it partially).
b. indicate that the operation has failed by setting the stream to a failed state.

to send a newline to the output stream use stm << '\n' ;
use stm << std::endl if you want to flush the stream buffer immediately after inserting the newline.
   std::cout << std::endl ;
is equivalent to
   std::cout << '\n' << std::flush ;
flushing a stream buffer could be an expensive operation, do it only if you really need it.

that out of the way, let us look at the prefix and postfix increment operators.
to use the getTmin() to convert first the time to minutes , increment or decrement it and then reconvert it back,
a. invoke getTmin() to get number of minutes.
b. add one to it to increment the value.
c. use the constructor Time::Time( int _asMin ) to convert the result to a Time
d. assign the result to the object to implement the increment.

 #include <iostream>
 #include <stdexcept>
 using namespace std;

 class Time
 {
   public:
     Time(int _hr, int _min) : min( _min ), hr( _hr )
     {
       if( ( hr >= 0 && hr < 24 ) || ( min >= 0 && min < 24 ) )
         throw std::range_error( "incorrect time" ) ;
     }

     enum { MINUTES_PER_DAY = 60 * 24 } ;

     explicit Time( int _asMin = 0 )
     {
       if( ( _asMin < 0 ) || ( _asMin >= MINUTES_PER_DAY ) )
         throw std::range_error( "incorrect time" ) ;
       hr = _asMin/60; min = _asMin%60 ;
     };


     friend ostream &operator<<(ostream &out, const Time &t2);
     friend istream &operator>>(istream &in, Time &t2);
     Time operator++(int); //postfix increment
     Time& operator++();  //prefix increment
     int getTmin(){return hr*60 + min;}
     // etc
   private:
     int min;
     int hr;
     // int count;
 };

 Time Time::operator++(int)
 {
   Time old = *this;
   ++*this ; // do exactly what prefix increment does
   return old;
 }
 Time& Time::operator++()
 {
   *this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY ) ;
   return *this;
 }

 ostream &operator<<(ostream &out, const Time& t2 )
 { return out << t2.hr << ' ' << t2.min ; }

 istream &operator>> ( istream &in, Time& t2 )
 {
   int hr, min ;
   if( ( in >> hr >> min ) &&
       ( hr >= 0 && hr < 24 ) && ( min >= 0 && min < 60 ) )
       {
         t2.hr = hr ;
         t2.min = min ;
       }
   else in.clear( ios::failbit ) ; // set stream to failed state

   return in ;
 }

 int main(void)
 {
   Time time;
   cout << "Enter time :" ;
   cin >> time;
   cout << time++ << '\n' ;
   cout << ++time << '\n' ;
 }




---------- FOLLOW-UP ----------

QUESTION:  I have only taken the pre and post increment functions for further use here.could you clarify this further please, first have i modified it correctly? so that if i enter 10:00 as time, and i want it to print time++(post incremnt), that gives 10 and if i want it to print ++time,(pre increment) that gives me (12:00):

Time Time::operator++(int)
{
  Time old = *this;
 *this =Time(( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
  ++*this ; // do exactly what prefix increment does
  return old;
}
Time& Time::operator++()
{
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
  return *this;
}

Also, you gave the following :

to use the getTmin() to convert first the time to minutes , increment or decrement it and then reconvert it back,
a. invoke getTmin() to get number of minutes.
b. add one to it to increment the value.
c. use the constructor Time::Time( int _asMin ) to convert the result to a Time
d. assign the result to the object to implement the increment.

now why isn't the statement this then:
getTmin() + 1 ) % Time::MINUTES_PER_DAY )?

Then finally,

is this exactly what u wrote :
else in.clear( ios::failbit ) ; // set stream to failed state? i couldn't see this particular statement properly, so just to be sure.

thanks and looking forward to getting ur take on these.  

Answer
> so that if i enter 10:00 as time, and i want it to print time++(post incremnt), that gives 10

right. the time is incremented to 10:01 (by one minute).

> and if i want it to print ++time,(pre increment) that gives me (12:00)

no, the increment is by one minute, not one hour.
if time is currently 10:01, and you print ++time (prefix incremnt), that prints 10:02


> now why isn't the statement this then:
> getTmin() + 1 ) % Time::MINUTES_PER_DAY )?

the time you try to increment could be 23:59
the modulo division by Time::MINUTES_PER_DAY rounds it off to the next day.

> is this exactly what u wrote :
> else in.clear( ios::failbit ) ; // set stream to failed state

yes.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.