2

I have a question that is similar to the question that was asked here: How does "this" cascading work?

Suppose I have the following code:

#include <iostream>
using namespace std;

class Time
  {
  public:
     Time( int = 0, int = 0, int = 0 );
     Time setHour( int );
     Time setMinute( int );
     void print( void );

  private:
     int hour;
     int minute;
  };

  Time::Time(int hr, int mn, int sc)
  {
     hour = hr;
     minute = mn;
  }

  void Time::print( void )
  {
     cout << "hour = " << hour << endl;
     cout << "minute = " << minute << endl;
  }

  Time Time::setHour( int h )
  {
     hour = ( h >= 0 && h < 24 ) ? h : 0;
     return *this;
  }


  Time Time::setMinute( int m )
  {
     minute = ( m >= 0 && m < 60 ) ? m : 0;
     return *this;
  }

int main()
{
   cout << "Hello, world!" << endl;
   Time t;
   t.setHour( 10 ).setMinute( 25 );
   t.print();
}

Then, it is clear that the function setMinute( 25 ) is not running on the Time object t. Note that the functions setHour and setMinute do not return references to Time objects.

What is happening after t.setHour( 10 ) executes? Does the function setHour somehow return a "copy" of the object t, and setMinute( 25 ) is running on the copy? I have compiled the program with -Wall and no errors or warnings are returned.

Thanks for your assistance.

Community
  • 1
  • 1
jrand
  • 279
  • 1
  • 3
  • 9

2 Answers2

4

Your analysis seems correct. This expression

t.setHour( 10 )

returns a temporary Time object. You then call setMinute(25) on that temporary. This in turn returns another temporary Time object, which is not assigned to anything. So setHour() acts on the t instance, but setMinute() acts on a temporary, which disappears at the end of this line

t.setHour( 10 ).setMinute( 25 );
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
0

Each of t's methods return a reference to t. A reference is an alias. So if you did

Time t;
 Time& tAgain = t;
 tAgain.setMinute( 25); 
tAgain.setMinute also alters t's time.

Now extrapolate that simple example to cascading. Each method of t returns a reference to itself

Time &Time::setSecond( int s ) 
  {
      second = ( s >= 0 && s < 60 ) ? s : 0; 
      return *this; 
  }

So in the expression:

   t.setHour( 10 ).setMinute( 25 )

t.setHour( 10 ) calls setHour on t, then returns a reference to t. In this case the reference is temporary. So you can think of it as if the above line changed to the following on evaluating setHour:

tAgain.setMinute(25);

t.setHour returned a reference -- similar to our tAgain above. Just an alias for t itself.

Ravindra Bagale
  • 17,226
  • 9
  • 43
  • 70