Shapes 2: Inheritance with non-virtual functions.
=================================================


The examples here use the same definitions of Shape and Circle as were used 
in Part 1 of this tutorial.  (In the Shapes_1 directory.)  Here, however, the 
client code (in main.cpp and main_1.cpp), illustrates some more features and 
usage of C++.  We'll call these code examples Example 1 (w/ main.cpp) and 
Example 2 respectively.

What these examples have in common is that they both demonstrate non-polymorpic 
behaviour.  That is, they show what happens when a given non-polymorphic (*) 
member function is overridden - redefined at various levels in an inheritance 
hierarchy.  Despite this redfinition, where a member declared and defined as 
is done here, when the function is invoked by name, using a base class pointer
or reference, it is the base class version of the function that will be called.

Example 1 shows this effect in the context of iteration over a logically 
heterogenious collection of objects.  Example 2 shows the same (non-polymorphic) 
behaviour in the cases of call by value, and call by reference or pointer.


Example 1 - further aspects:

The function main() shows a number of capabilities of the language, such as:
  - the ability and a mechanism create objects at run-time, using memory which
    is dynamically allocated using operator "new".  (We will see in a later
    example how this can be used to allow the numbers and types of objects 
    created to be chosen at run-time.)
  - the use of a standard library collection class (vector<>, a class template)
    to store a collection of objects.
  - how this collection can be, logically, a heterogenious collection 
      - i.e. containing objects of different types.
  - the use of shared_ptr, one of the standard smart pointers 
  - how the use of the arrow "->" operator can invoke a member function of a 
    pointed-to object, by a (raw or smart) pointer.
  - the use of "auto", and the range-based for loop.


Notice that when run, both the draw() functions report the object to be a 
Shape.  We might prefer the second draw() to report that the object involved
is a Circle.  As indeed it is; but it is also a Shape.  A Circle is AKO Shape.
In the main.cpp code, the draw() function being invoked is based on the pointer
type (a pointer to Shape), rather than the pointee type, a Circle.  If we want
to report based on the pointee type, then we need to do something else, 
something slightly different.  (As is done in the corresponding example for the 
next step, in the Shapes_3 directory.)

The code of main.cpp will require the use of C++11 (although with slight 
modifications it could be written to use C++98).  As it stands, it will require
the use of a C++11-aware compiler.  Say g++ 4.6.3 or later.  (**)


You can compile and build the program using the suggested build lines:

g++ -std=c++0x main.cpp shape.cpp circle.cpp -o shapes

or, if you are using g++ 4.7 or above:

g++ -std=c++11 main.cpp shape.cpp circle,cpp -o shapes

Note that when run, both the Shape and the Circle report themselves as being
Shapes.


Example 2 - further aspects:

This example uses a different version of main(), in file main_1.cpp.

The example here shows the effect of calling a (non-virtual) draw() member 
function on passed objects of Shape and Circle types, when these are passed 
by value, (const) reference, and address.  In these cases the base class 
(Shape's) draw function is always called, even when a derived object is 
passed.

Build lines are as above, simply substituting main_1.cpp for main.cpp,
and probably chosing a different name for the built program.

It is, however, suggested that you defer building and running this example 
until after you have worked through the next Step, in directory Shapes_3.  
(When you do build and run the program here, in Shapes_2, all of the shapes 
involved report themselves as being Shape objects - i.e. the Circle c 
always reports itself as a Shape.)


(*) Polymorphic and Non-Polymorphic
===================================

The member functions used here are non-polymorphic.  What that - and its 
opposite - means will be covered in the next step of the exercises.


(**) g++ versions for C++11
===========================

To find out your g++ version, enter the command g++ --version.
g++ 4.3 and later support -std=c++0x for experimental inplementations of C++11
g++ 4.7 and later support -std=c++11
(See http:g++.gnu.org/projects/cxx0x.html for some gory details)

Asides: The g++ --version currently shows as 4.6.3 on a vanilla, but updated, 
Ubuntu 12.04, and also, at the time of writing, on a standard Raspbian 
installation on a Raspberry Pi.  This version of g++ is fine for the 
examples here.  

It is also, of course, possible to install later versions, and even run with 
multiple, selectable versions.  But we will not cover this here.

