Construction, Destruction, References, and Function Overloading
===============================================================

This example illustrates a number of points around the use of references, 
recaps some topics seen earlier, and introduces a few new ones.  It uses a new 
class, Sheep to do this.


Things to note in the source code:

There are two versions of the code with main().  The fuller one is main.cpp; 
but there is also a simpler version, main_simple.cpp.  The latter simply 
creates two sheep objects.  Then, of course, these are destroyed as main() 
exits.  Both construction and destruction are instumented, so that you can 
see reports as the objects are created and destroyed.

It is suggested that you first look at main_simple.cpp, then build it with:

g++ main_simple.cpp sheep.cpp -o sheep_simple

, then observe the output as it runs.


(In this example we're using instumented constructors and an instrumented
destructor.  These are declared and defined in sheep.h and sheep.cpp, 
respectively.  Note that these same sheep files are also used in the slightly
more complicated main.cpp version; for this they have some additional 
facilities which are unused in the simple example.)


The second example, with main.cpp, is similar to the first; but is slightly 
more involed. 

   - there are two constructors: one that takes a string and uses it to 
     construct a Sheep; and a second one that takes a pre-existing sheep,
     and constructs a second one out of the first.  This is known as a copy
     constructor.  In general a copy constructor for a class C takes an 
     argument of type const C&.  Think about it - what else could it take?
     If it took a C by value, then we would be defining the copy function,
     and before getting into the body of this definition, we would be using
     that definition to do the argument copy to initialize the parameter! 
     So the parameter has to be a reference; and we want it to be a const 
     reference to leave the original argument unmodifyable by the function.
   - notice that the copy constructor has access to a private member of its
     Sheep argument.  This is allowable because privacy is class-wide, rather
     than on a per object basis.  A member function of a class can directly
     access the private members of any other instances of the same class that 
     it has access to (e.g. by the instance being passed as a parameter into 
     that function.) 
   - the ability to have mmultiple versions of a function with a given name,
     differing only in argument types (or constness), is known as overloading.
   - it is not uncommon to have multiple constructor definitions, i.e. 
     overloaded constructors.

   - we are providing diagnostic instrumentation in the constructors, and in
     the destructor.

Build the code in the obvious way, i.e. g++ main.cpp sheep.cpp -o sheep
and run it as usual.

Notice the order of the output messages, and in particular the order of 
construction and destruction shown.  That is, destruction is in the reverse
order to construction.

We have declared and defined a free function (i.e. non-member function) in 
this example, taking a const reference parameter.  This is a typical way to 
pass an object into a function.  

(Aside: What is not particularly typical is to declare and define it in the 
file where it is used.  Indeed, even the use of the declaration:

void say_hello( const Sheep &sheep );

is redundant in this case, because the function definition immediately below 
it also serves as a function declaration, providing all that is needed to 
call it in main().

What is needed is only this declaration somewhere above the point of its use
(in main(), here).  It would be more typical to have the declaration only in 
the client code file(s) (main.cpp here), and perhaps imported via a #include; 
and the for the function definition to be in another .cpp file, compiled 
separately, and linked in when building the program.  

We have used the layout as shown for simplicity in seeing all of the relevant 
code in a single file, in a single window.)

