You are here:

C++/concise explanation to this code..

Advertisement


Question
QUESTION: hello Vijayan,

i was studying a c++ code that demonstrates the increment both prefix and postfix operator but i was abit confused about certain statements in the code. please, clarify me more on each one of them. below is the code:


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

class Time
{
       int min;
       int hr;
  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
  
   
    
};

Time Time::operator++(int)
{
  Time old = *this;
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
    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' ;
  
 system("PAUSE");
 return(0);
}

questions:

1. how many constructor is the Time class using? i seen one normal Time(int _hr, int _min) constructor but there is also the explicit Time() pls what is the explicit Time(int _asMin = 0) function doing there.

2.In the prefix operator  function: Time operator++(int);
there is this statement :
Time old = *this;
*this = Time( ( getTmin() + 1 ) % Time::MINUTES_PER_DAY );
    return old;
why are we interested in setting the *this pointer to the Time old? Also, why is the MINUTES_PER_DAY enum accessed using the scope Time::MINUTES_PER_DAY? is it because MINUTES_PER_DAY is an enumerated variable?

These are my confusion. i hope to get a clearer understanding of this code after this questions are answered. thanks alot.

ANSWER: > how many constructor is the Time class using? i seen one normal Time(int _hr, int _min) constructor but there is also the explicit Time() pls what is the explicit Time(int _asMin = 0) function doing there.

class Time has two constructors;

Time(int _hr, int _min) : min( _min ), hr( _hr ) ;
explicit Time( int _asMin = 0 ) ;

A class can have as many constructors as we want; constructors can be overloaded.
For the meaning and rationale of the explicit keyword, see:
http://weblogs.asp.net/kennykerr/archive/2004/08/31/Explicit-Constructors.aspx


> why are we interested in setting the *this pointer to the Time old?

The result of post-fix increment operator i++ ods the value of i *before* it is incremented. this is a pointer to the Time being incremented, *this dereferences the pointer to get a reference to the Time that is being incremented.

Time old = *this ;

therefore makes a copy of the Time object *before* it is incremented. This copy (old) is what is returned as the result of the operation.

> why is the MINUTES_PER_DAY enum accessed using the scope Time::MINUTES_PER_DAY? is it because MINUTES_PER_DAY is an enumerated variable?

The enumerated value MINUTES_PER_DAY is within the class Time (not at the global scope). So the scope has to be given using the scope resolution operator (::). Time::MINUTES_PER_DAY means the MINUTES_PER_DAY defined within Time (and not anywhere else).







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

QUESTION: why are these two functions different and how does the const. affect them?

const float& Array::operator[] (int i) const
{
       
       return c_array[i];
       }
float& Array::operator[] (int i)
{
       
       return c_array[i];
       }

ANSWER: Let us say we have a function:

void our_function( const Array& const_arr, Array& arr )
{
  std::cout << const_arr[3] << '\n' ;
  // const_arr is a const Array; this calls const float& Array::operator[] (int i) const
  // we can inspect the element, but cannot modify it since we get a reference to a float that is const

  arr[3] = 5.76f ;
  // arr is a non-const Array; this calls float& Array::operator[] (int i)
  // we can inspect the element, and can also modify it since we get a reference to a float that is non-const
}

In this function, the const_arr is a constant (non-mutable) object, we should not be able to modify it. The elements of const_arr can be accessed by us, but cannot modified.

arr is a non-const (mutable) object; we should be able to modify its contents. The elements of arr can be accessed by us, and we can also modify them.

Also see: http://www.parashift.com/c++-faq-lite/const-correctness.html
It is worthwhile reading all the FAQs in this section.
FAQ http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12 deals specifically with your question.




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

QUESTION: hello,

i was really looking to see a small code that justifies this. such that if i try to modify it, i get a compiler error because the first method is a const reference to float while if i try to use the mutable method, it works. thatz what i was looking for. something to try and see for myself and help me remember ..
hope you can do that for me.

thanks

Answer
Try compiling this code:

struct int_array_10
{
       int_array_10() { for( int i=0 ; i<10 ; ++i ) a[i] = i ; }

       int& operator[] ( int pos ) { return a[pos] ; }

       const int& operator[] ( int pos ) const { return a[pos] ; }

       private : int a[10] ;
};

void function( int_array_10& a, const int_array_10& ca )
{
       int i = a[5] ; // fine

       a[5] = 12345 ; // fine, a is modifiable, every element of a is therefore modifiable

       i = ca[5] ; // fine, we are not trying to modify ca

       ca[5] = 12345 ; // **** error: can't modify a const int
       // ca is non-modifiable; an element of ca is therefore non-modifiable
}

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++09. i would not answer questions about gui and web programming.

Experience

over 15 years

Education/Credentials
post graduate engineer

©2012 About.com, a part of The New York Times Company. All rights reserved.