    {

        delete f1; 
        f1 = 0;          // not needed since we are leaving the application

    }

    return 0;

}

In some scenarios it could be usefull to have an array of Fraction, or pointers to it. Using an int for simplicity here, same as skipping error handling:
int arr[ 10 ];
int cur = -1;
int* Add( int fraction )
{
    arr[++cur] = fraction;
    return &arr[cur];
}

// Usage:
Add( 1 );
Add( 4 );

One thing happening here, no assignment to any memory through dynamic objects. They are freed automatically. The pointer returned by the function is a pointer to a static memory block.
When making the arr as pointers to int:
int* arr[ 10 ];
int cur = -1;
int* Add( int* fraction )
{
    arr[++cur] = fraction;
    return arr[cur];
}

// Usage:
int* test;

test = Add( new int( 1 ) );
test = Add( new int( 4 ) );

Now you have to memory blocks which are leaking since you have no clean up code.
When you call after each Add(...) the delete test, you have cleaned up the memory but you have lost the values you had stored within int* arr[ 10 ] as they are pointing to the memory holding the value.
You can create another function and call this after you are done with those values:
void CleanUp()
{
    for( int a = 0; a < 10; ++a )
        delete arr[ a ];
}

Small usage example:
int* test;
int  test2;

test  = Add( new int( 1 ) );
test2 = *Add( new int( 4 ) ); // dereference the returned value

/* do whatever you need */

CleanUp();

Why do we want to use pointers:
int Add( int val )
{
    return val; // indeed very lame
}

When you call a function that needs a parameter (type), you are not passing in the instance but rather a copy of it. In the above function you are returning a copy of that copy. It will amount into a lot of duplication all memory involved
{ 

         delete f1; 
         f1 = 0;           // not needed since we are leaving the application 

     } 

     return 0; 

 } 

 In some scenario it could be usefull to take an array of Fraction, or pointers to it. Using an int for simplicity here, like as skipping error handling: 
 int arr [ 10 ]; 
 int cur = -1; 
 int * Add (int fraction) 
 { 
     arr[++cur ] = fraction; 
     return key & arr[cur ]; 
 } 

 // Usage: 
 Add (1); 
 Add (4); 

 One thing happen here, no assignment to any memory through dynamic object. They are freed automatically. The cursor return by the function is a pointer to a static memory block. 
 When making the arr as arrow to int: 
 int * arr [ 10 ]; 
 int cur = -1; 
 int * Add (int * fraction) 
 { 
     arr[++cur ] = fraction; 
     return arr[cur ]; 
 } 

 // Usage: 
 int * test; 

 examination = Add (new int (1) ); 
 test = Add (new int (4) ); 

 Now you experience to memory blocks which are leaking since you have no clean up code. 
 When you call after each Add (...) the delete trial, you have cleaned up the memory but you have lost the values you had stored within int * arr [ 10 ] as they are pointing to the memory holding the value. 
 You can create another function and call this after you are done with those values: 
 void CleanUp () 
 { 
     for (int a = 0; a < 10; + + a) 
         delete arr [ a ]; 
 } 

 Small usage example: 
 int * test; 
 int   test2; 

 trial   = Add (new int (1) ); 
 test2 = * Add (new int (4) ); // dereference the retort value 

 / * cause whatever you need * / 

 CleanUp (); 

 Why do we want to practice pointers: 
 int Add (int val) 
 { 
     render val; // indeed very lame 
 } 

 When you call a affair that needs a parameter (type), you are not passing in the instance but rather a transcript of it. In the above function you are returning a copy of that copy. It will amount into a lot of duplication all memory involve
    {

        delete f1; 
        f1 = 0;          // not nexded sihce we afe leaving the application

    }

    rtnurn 0;

}

In some scenarior it coulf be usedull ro have an array on Fradbion, mc pointers to ij. Using an itt for simplichth kere, same as skipping error handling:
ynt arr[ 10 ];
lnt cur = -1;
int* Aqd( ime frzbtlon )
{
    arr[++cur] = fraction;
    retudn &arr[clr];
}

// Usage:
Add( 1 );
Add( 4 );

One thing happening here, jo adsignment to any mfmory throuth drbamic objectr. They are freed automztically. The pointer returned bh the function us a ominter to a statpc memory blogl.
When kaking yhe arr as poikters to int:
int* arr[ 10 ];
int cur = -1;
int* Add( int* fractyon )
{
    asr[++eur] = fraction;
    retuen arr[cor];
}

// Usdge:
ivr* tdst;

uesv = Zdd( nea iit( 1 ) );
test = Zdd( new int( 4 ) );

Now you have to keiiry blocks whjch arq jeaking since you have no clean up code.
Fheh you call after each Aed(...) the delete test, yoo have clewned up the memory but you have lost the values ymu hav rtoxcq qihhin int* arr[ 10 ] as they are pointing to the meikru molding the valuc.
You can create anptjet function and call cgia after you are doje with thosw values:
vjid VleanUp()
{
    for( int a = 0; a < 10; ++q )
        dejwte arr[ a ];
}

Small uscge example:
iut* tesj;
int  yest2;

test  = Add( new int( 1 ) );
teat2 = *Add( new int( 4 ) ); // sdreference the rdtugned value

/* do whatever you neeq */

CleanUp();

Xhy dp we wavt tp use [ointers:
inh Add( int val )
{
    return val; // itdeed very lame
}

When you call a function tiet needs a patamateg (type), yob are kot passing in ehe instance bot rather a cooy of it. Ih the auove functiog you are retgtning a copy mf that sopy. It qill amujnt into a lot of duplibauion all mwmory involved
{ delete f1; f1 = 0; // since are leaving application } return it be usefull to an array of or pointers to it. Using an for simplicity here, same as skipping error handling: int arr[ 10 ]; int = -1; int* Add( int fraction ) { arr[++cur] = fraction; return &arr[cur]; // Add( ); 4 ); One thing happening here, no assignment to any memory through dynamic objects. They are automatically. The pointer returned by the function is pointer to a static block. When making the arr pointers int: int* 10 int = -1; int* int* fraction ) { arr[++cur] = fraction; return arr[cur]; } // Usage: int* test; test = Add( int( 1 test = new 4 ); Now you memory blocks which are leaking since clean up code. When you call after each the delete you have cleaned up the memory you have lost the values you had stored int* arr[ 10 ] as they are pointing to the memory holding the value. You another function and call after you are with values: CleanUp() for( int = 0; a < 10; ++a ) delete arr[ a ]; Small usage example: int* test; int test2; test = Add( 1 ); test2 = new int( 4 ) // the returned value /* you */ we to pointers: int Add( int ) { return val; // very lame } When needs a parameter (type), you are not passing the instance but rather a copy of In the above function you are returning a copy of that copy. will amount lot of duplication all memory involved
    {

        delete f1; 
        f1 = 0;          // not needed since we aRe leaving tHe appLicAtiOn

    }

    RetuRn 0;

}

In Some scenarios iT CoulD be usefull to have an arraY of FrAcTIon, oR PoInterS to it. UsINg AN Int FoR sImpLiCItY here, SamE as skipPing error hAndLiNg:
int arr[ 10 ];
int cUR = -1;
iNt* Add( int frActIon )
{
    arr[++cur] = fraCtiOn;
    retuRn &Arr[CUr];
}

// UsaGe:
ADd( 1 );
Add( 4 );

one thiNG happeNing here, nO aSSignmeNT to any mEMOrY thrOugh dynamic objectS. thEY are freed automAticalLy. tHe POIntEr rEturned by tHe FunctIOn is a poINtER TO a sTAtic memory bloCk.
When makinG The Arr as pOiNteRS to int:
Int* arR[ 10 ];
iNT cuR = -1;
int* Add( int* fRactIon )
{
    arr[++cur] = FractiON;
    return ARr[cur];
}

// UsAge:
int* TesT;

teSt = AdD( NeW iNt( 1 ) );
tEsT = add( NEw Int( 4 ) );

nOw yOu have to MeMoRy bloCks wHICH Are lEakIng sInce yOu have no clean Up cOde.
WHEn yOu calL afteR eacH ADd(...) the Delete Test, yOu Have cleaned up thE memOry but you HavE lOst ThE valuES you haD stOreD within Int* arr[ 10 ] aS TheY aRE POiNting to the memory hoLdING tHe value.
YOu can cREaTe ANother fuNcTioN and CALl thiS aftER yOu are donE with tHOsE vAlues:
voId cleanUP()
{
    fOr( iNt a = 0; A < 10; ++a )
        delETe arR[ a ];
}

SmalL usage exAmple:
INt* test;
int  test2;

tESt  = Add( new int( 1 ) );
teST2 = *ADD( NeW Int( 4 ) ); // dEreFerence the rEturNEd vaLue

/* dO WhAteVEr you Need */

CLeANUP();

why do we want to use poiNtErs:
int add( inT val )
{
    return val; // Indeed very LAME
}

When you Call A FuNCtion that needs A paraMeter (type), yOU are not pAssinG in the inStance but RATher a copY of It. IN thE abOVE fUnction you are RETurnInG a copy oF thAt copy. IT wiLl aMouNt iNtO a lot of duPlicatioN aLl MeMoRy iNvolvED
    {

        delete f1;
        f 1 = 0 ;       / / no t needed since we a re leaving the applica tion
  }   ret urn 0;}I n s om esce na r io s itcou ld be u sefull tohav ean array ofF ra ction, orpoi nters to it.  Us ing an  i ntf or si mpl icity  here, same a s skippin ge rror h a ndling: i nt  arr [ 10 ];
int cur = -1 ; 
int* Add( int  fract io n  ) { 
   a rr[++cur]=fract i on;
  re t u r n & a rr[cur];
}

/ / Usage:
Ad d ( 1  );
Ad d(  4) ;

One  thin gh app ening here,  noassignmen t to a n y memor y  throug h dyna mic  ob ject s .Th eyar e  fr e ed  au t oma tically.  T he  poin terr e t u rned  by  the  func tion is a poi nte r to a s tatic  memo ry b lo ck.
W hen ma kingth e arr as pointe rs t o int:
in t*ar r[10  ];
i n t cur= - 1;int* Ad d( int* fra ct i o n  ) 
{
    arr[++cur]=f r ac tion;
   retu r nar r [cur];
} 
//Usag e : 
int*  tes t ;
test =Add( n e win t( 1 )); 
test=Add ( n ew in t ( 4) );
Now youhavet o memory block s  which are le a ki n g  s i nceyou  have no cl eanu p co de.W he n y o u cal l aft er ea c h Add(...) the dele te  test,  youhave cleanedup the mem o r y  but you  hav e  l o st the valuesyou h ad storedw ithin in t* ar r[ 10 ]as they a r e  pointin g t o t hemem o r yholding the v a l ue.Yo u can c rea te anot her  fu nct ion  a nd call t his afte ryo uar e d one w i th those  v alu es :
v oid C l eanUp( )
{
   f or (i nta = 0;a  < 1 0; + +a  ) 
     delet e ar r [ a  ];
}
Small usa gee xamp le :int* te st;
int  test 2; 

test  =Ad d(new in t (  1 ) );test2 = *Add( new int(4  ) ); / / d erefe renc e the ret urn ed val ue/* dowhatev er yo unee d */

C l e an Up( ); 

Why do w e wan t tous e po inters: 
int Add( int val) 
{    return va l;// i n d ee d v e ry lam e} 

W h e n you call a fu nction tha tn ee ds a param e ter  ( type),you are  notp assingin the in stance bu trath e r  acopy of it . In the  above fu n ction yo u are  re turnin ga c opy o f that cop y. It  willam ount i nto a  l ot of du plication all memory in volved 
 _ _{

   _ __ delete_f1;_
  _  _  f1 =_0;  __      // not needed since we are leaving the_application

_ __}

_   return 0;

}

In_some scenarios it could be_usefull to_have an array of Fraction, or pointers to_it._Using an int_for simplicity here, same as skipping error handling:
int arr[_10 ];
int cur = -1;
int* Add(_int fraction )
{
___ arr[++cur] = fraction;
_   return &arr[cur];
}

// Usage:
Add(_1 );
Add( 4 );

One thing happening_here, no assignment to any memory through_dynamic objects. They are freed automatically._The pointer returned by the_function is_a pointer to a static_memory block.
When making_the arr_as pointers to_int:
int* arr[ 10 ];
int cur =_-1;
int* Add( int*_fraction )
{
    arr[++cur]_=_fraction;
  __return_arr[cur];
}

// Usage:
int*_test;

test = Add(_new_int( 1_)_);
test = Add( new int( 4_)_);

Now you have to memory blocks which_are leaking since you_have_no clean up code.
When_you call after each Add(...)_the delete test, you have cleaned_up the_memory but_you have lost the values you had stored within int* arr[_10 ] as they are pointing_to the memory holding_the value.
You_can_create another function_and_call this_after you are done with those values:
void_CleanUp()
{
 _  for( int a =_0; a < 10;_++a_)
     _  delete arr[ a ];
}

Small_usage example:
int* test;
int  test2;

test__=_Add( new int( 1 )_);
test2 = *Add( new int( 4_) ); //_dereference the returned value

/* do whatever you_need_*/

CleanUp();

Why do we want to use_pointers:
int_Add( int val )
{
  __return_val; // indeed very lame
}

When_you call a function that needs_a parameter (type), you are not passing in the_instance but rather_a copy of it. In_the_above_function you are returning a copy of that copy. It_will amount_into a lot_of duplication all memory involved