<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

%===================================================================
% Include common packages, environments, counters etc
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_lab_format}
\input{common_latex/common_latex_definitions}
%===================================================================

\begin{document}
\wikidoc{file=Lab.CPPInherit}
\wikidoc{auth=mikerb@mit.edu}

%===================================================================
% Build the Cover Page in an environment style easy for wiki parsing
\begin{labcover}
\labtitle{C++ Lab 08 - Class Inheritance in C++}
\vspace{0.1in}
\labcourse{2.680 Unmanned Marine Vehicle Autonomy, Sensing and Communications}
\vspace{0.2in}
\labpng{0.775}{figures/tsl.png}
\vspace{0.3in}
\labdate{IAP 2024}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\vspace{0.2in}
\labtoc{small}
\end{labcover}

%======================================================================
% Add a blank page so first body page is on the right when doubleside
\blankpage

%======================================================================
% Begin the body of the text

%======================================================================
\section{Lab Eight Overview and Objectives}
%======================================================================

In this lab C++ class inheritance (sub-classing) is explored. This is
one of the key capabilities in object-oriented program and is a prime
distinction between C and C++. In MOOS-IvP it is also a key concept
since all MOOS apps inherit from a MOOSApp superclass and all IvP Helm
behaviors inherit from a IvPBehavior superclass. In this lab we will
build a couple simple subclasses of the \var{SegList} class used
previously in Lab 05.

\pskip
\noindent
In this lab the following topics are covered.

\begin{labinfo}
\begin{packed_itemize}[2]
\item C++ Subclasses
\item Polymorphism
\item Encapsulation
\item Function Overloading
\item Virtual Functions 
\end{packed_itemize}
\end{labinfo}

%=======================================================================
\section{Subclasses and Inheritance in C++}
%=======================================================================

Class inheritance is a key part of C++ and object oriented languages
in general. It allows for a natural way of organizing code and a form
of {\em code re-use} in functions higher in the hierarchy usable by
sub-classes. It complements the {\em has-a} relationship with the {\em
  is-a} relationship. The following couple links provide a good
introduction:

\vspace{0.1in}
\begin{packed_itemize}
\item You can skip Section 11.7 on Multiple Inheritance \newline
  \urlx{http://www.learncpp.com/cpp-tutorial/111-introduction-to-inheritance}

\item You can skim or skip the sections on Friend Classes and Multiple
  Inheritance. \newline
  \urlx{http://www.cplusplus.com/doc/tutorial/inheritance}
\end{packed_itemize}
\vspace{0.1in}

\noindent
After you've read the above link(s), you should be ready for a couple
short exercises.

%=======================================================================
\refstepcounter{exercise}
\label{ex_shapes_v1}
\subsection{Exercise \ref{ex_shapes_v1}: Creating a Simple Subclass of the SegList Class}

Create two subclasses of the \var{SegList} class created in lab 05,
called \var{Triangle} and \var{Square}. For now, these two classes
will do nothing more than overload the \var{getSpec()} function. The
overloaded function should invoke the \var{getSpec()} function already
implemented in the \var{SegList} superclass. The overloaded function
should simply add the type to the output of the string spec. 

\pskip
\noindent
HINT: To see how to invoke a superclass function from within a
subclass function, it's worth taking an extra careful read of the
section {\em Adding to Existing Functionality} in Section 11.6 in the
\var{learncpp.com} URL above.

\pskip
\noindent
In this exercise we will test the two new classes with a simple
\var{main()} function that creates a \var{Triangle} instance and \var{Square}
instance with vertices:

\vspace{0.1in}
\begin{packed_itemize}
 \item \var{(0,0)}, \var{(10,0)}, and \var{(5,5)}
 \item \var{(0,0)}, \var{(10,0)}, \var{(10,10)}, and \var{(0,10)}
\end{packed_itemize}
\vspace{0.1in}

\noindent
After instantiating and populating two instances, with the above
vertices, just output the result of \var{getSpec()} to the terminal.
\vspace{0.1in}

\noindent
Call your files \var{Triangle.cpp/h}, \var{Square.cpp/h} and
\var{shapes\_v1.cpp} and build it to the executable \cmd{shapes\_v1}. When your
program runs it should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./shapes_v1
 Triangle: type=triangle,x=0,y=0,x=10,y=0,x=5,y=5
 Square:   type=square,x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_shapes_v1}.  

\vspace{0.12in}
\noindent

{\bf Building shapes\_v1}: From the previous lab on Build Systems and
Makefiles, you should be able to make a simple Makefile for this
exercise. If you'd like to peek ahead at a Makefile for all five
exercises in this lab, see Section \ref{sol_makefile}.
%-------------------------------------------+

%=======================================================================
\refstepcounter{exercise}
\label{ex_shapes_v2}
\subsection{Exercise \ref{ex_shapes_v2}: Using Inherited Superclass Functions}

In this exercise, add a function to the \var{SegList} superclass to
calculate the "perimeter" of the line segements, including the
distance from the end vertex back to the first vertex. This short
exercise demonstrates a form of code re-use through inheritence. Call
your new function \var{getPerimeter()} and implement it on a copy of
the \var{SegList} class called \var{SegListV2}.  You will also need to
slightly modify your \var{Triangle} and \var{Square} classes to use
the new superclass, so call them \var{TriangleV2} and \var{SquareV2}
respectively. Your \var{main()} function in \var{shapes\_v2.cpp} will
only be modified to show the newly calculated perimeter on the same 
example shapes as the first exercise. When your
program runs it should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./shapes_v2
 Triangle:   type=triangle,x=0,y=0,x=10,y=0,x=5,y=5
  Perimeter: 24.1421
 Square:     type=square,x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
  Perimeter: 40
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_shapes_v2}.  

{\bf Building shapes\_v2}: From the previous lab on Build Systems and
Makefiles, you should be able to make a simple Makefile for this
exercise. If you'd like to peek ahead at a Makefile for all five
exercises in this lab, see Section \ref{sol_makefile}.
%-------------------------------------------+

%=======================================================================
\section{Polymorphism}
%=======================================================================

The term {\em polymorphism} refers to the ability to have several functions,
with the same name, do different things depending on which class is invoking
the function. A simple example of polymorphism:

\vspace{0.1in}
\begin{fileverb}
 1 + 2       // Integer addition
 1.1 + 2.2   // Floating point addition
 "1" + "2"   // String concatenation
\end{fileverb}
\vspace{0.1in}

\noindent
Another example is when different classes have the same function
defined, even with same semantic meaning, but behavior differently
depending on the class. For example, in our next exercise we define
the \var{getArea()} function on both the \var{Triangle} and \var{Square}
classes, but the function is implemented differently to reflect the
different way that area is calculated. Before proceeding to this exercise, 
have a read of:

\vspace{0.1in}
\begin{packed_itemize}
\item \urlx{http://www.cplusplus.com/doc/tutorial/polymorphism}
\end{packed_itemize}
\vspace{0.1in}

%=======================================================================
\refstepcounter{exercise}
\label{ex_shapes_v3}
\subsection{Exercise \ref{ex_shapes_v3}: Using Polymorphism in our Shapes Example}

In this exercise, implement the \var{getArea()} function on both the
\var{Shape} and \var{Triangle} class. In both functions, a handy utility 
would be the ability to know the min and max x-y values of the vertices. 
To this end, implement the following four utility functions at the superclass
level:

\vspace{0.1in}
\begin{packed_itemize}
 \item \var{double getMinX() const;}
 \item \var{double getMaxX() const;} 
 \item \var{double getMinY() const;} 
 \item \var{double getMaxY() const;}
\end{packed_itemize}
\vspace{0.1in}

\noindent
Note that they are \var{const} functions since they don't alter the state
of the object, only report on existing properties. After you have implemented
these utility functions, implementing the \var{getArea()} function in both the 
\var{Triangle} and \var{Square} classes should be much simpler.


Implement your new \var{getArea() }functions on copies of the existing
classes, now called \var{TriangleV3.cpp/h} and
\var{SquareV3.cpp/h}. Implement your \var{getMin*()} utility functions
on a copy of the existing superclass, now called
\var{SegListV3.cpp/h}.  Your new \var{main()} function should be in
\var{shapes\_v3.cpp}, and will only be modified to show the newly
calculated area on the same example shapes as the first
exercises. When your program runs it should be invocable from the
command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./shapes_v3
 Triangle: type=triangle,x=0,y=0,x=10,y=0,x=5,y=5
     Area: 25
 Square:   type=square,x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
     Area: 100
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_shapes_v3}.  


\vspace{0.12in}
\noindent
{\bf Building shapes\_v3}: From the previous lab on Build Systems and
Makefiles, you should be able to make a simple Makefile for this
exercise. If you'd like to peek ahead at a Makefile for all five
exercises in this lab, see Section \ref{sol_makefile}.
%-------------------------------------------+

%=======================================================================
\refstepcounter{exercise}
\label{ex_shapes_v4}
\subsection{Exercise \ref{ex_shapes_v4}: Implementing Virtual Functions in our Shapes Example}

In this exercise we'll make a small but key addition to the problem
presented in the previous exercise. The goal is to be able to deal
with a mixture of both \var{Triangle} and \var{Square} instances in a
generic manner since they both have the same superclass. For example,
we should be able to have a container, such as a \var{vector} or
\var{list}, of such instances and add up all their areas, not caring
whether any of the instances is a \var{Triangle} or \var{Square}. In
these cases the containers will contain {\em pointers to the
  baseclass}. For example:

\vspace{0.1in}
\begin{packed_itemize}
 \item \var{vector&lt;SegList*&gt; my\_shapes;}
\end{packed_itemize}
\vspace{0.1in}

\noindent
In our example so far, it {\em is} possible to create the above type
of container, but if one were to try to invoke the \var{getArea()}
function on any of the instances, it would be disallowed since this
function is not defined on the \var{SegList} base class. To see this,
consider the below code snippet. This snippet assumes a valid
\var{Triangle} and \var{Square} instance have been created as with all
our prior exercises.

\vspace{0.1in} 
\begin{fileverb}
  SegListV4 *shape1 = &amp;triangle;
  SegListV4 *shape2 = &amp;square;

  cout &lt;&lt; "Triangle: " &lt;&lt; shape1-&gt;getSpec() &lt;&lt; endl;
  cout &lt;&lt; "    Area: " &lt;&lt; shape1-&gt;getArea() &lt;&lt; endl;
  cout &lt;&lt; "Square:   " &lt;&lt; shape2-&gt;getSpec() &lt;&lt; endl;
  cout &lt;&lt; "    Area: " &lt;&lt; shape2-&gt;getArea() &lt;&lt; endl;
\end{fileverb}
\vspace{0.1in} 

\noindent
In this snippet two base-class pointers are created, \var{shape1} and 
\var{shape2}, pointing to the \var{Triangle} and \var{Square} instance
respectively. This is fine, but if you tried to do this the compiler
would complain about the following two lines:

\vspace{0.1in} 
\begin{fileverb}
  cout &lt;&lt; "    Area: " &lt;&lt; shape1-&gt;getArea() &lt;&lt; endl;
  cout &lt;&lt; "    Area: " &lt;&lt; shape2-&gt;getArea() &lt;&lt; endl;
\end{fileverb}
\vspace{0.1in} 

\noindent
This is because the \var{getArea()} function is not defined (yet) on
the base class.  To overcome this, we can define the \var{getArea()}
function as a {\em virtual function} at the base class level. A
discussion on virtual functions can be found a the following URLs:

\begin{packed_itemize}
\item \urlx{http://www.cplusplus.com/doc/tutorial/polymorphism}
\end{packed_itemize}

\noindent
Your job in this exercise is to add the \var{getArea()} function as a
virtual function in the superclass. This modified superclass will be
called \var{SegListV4.cpp/h}. Also create \var{TriangleV4.cpp/h} and
\var{SquareV4.cpp/h} to use this new superclass. Confirm that the
above snippet works in your new \var{shapes\_v4.cpp} function.  When
your program runs it should be invocable from the command line with:

\vspace{0.1in}
\begin{consoleverb}
 $ ./shapes_v4
 Triangle: x=0,y=0,x=10,y=0,x=5,y=5
     Area: 25
 Square:   x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
     Area: 100
\end{consoleverb}

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_shapes_v4}.  

\vspace{0.12in}
\noindent
{\bf Building shapes\_v4}: From the previous lab on Build Systems and
Makefiles, you should be able to make a simple Makefile for this
exercise. If you'd like to peek ahead at a Makefile for all five
exercises in this lab, see Section \ref{sol_makefile}.
%-------------------------------------------+

%=======================================================================
\refstepcounter{exercise}
\label{ex_shapes_v5}
\subsection{Exercise \ref{ex_shapes_v5}: One Final Improvement to our Shapes Example}

You may have noticed that the output from the \var{getSpec()} function in 
the previous example is slightly different:

\vspace{0.1in}
\begin{consoleverb}
 Triangle: x=0,y=0,x=10,y=0,x=5,y=5
 Square:   x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
\end{consoleverb}

\noindent
Whereas before, in Exercise 3, it looked like:

\vspace{0.1in}
\begin{consoleverb}
 Triangle: type=triangle,x=0,y=0,x=10,y=0,x=5,y=5
 Square:   type=square,x=0,y=0,x=10,y=0,x=10,y=10,x=0,y=10
\end{consoleverb}

\noindent
Do you see the difference? Before addressing why this change occurred,
and fixing it here in this exercise, see if you can determine what caused
the change before reading on....

\pskip
\noindent
Once we start regarding our shapes generically, as in the previous 
exercise, with pointers to the base class, we need to be aware that
a invocation to a function like \var{SegList::getSpec()} will invoke
exactly that function, not the \var{Subclass::getSpec()} function. Unless
the base class function is virtual. Try making the \var{getSpec()} 
function in the base class virtual, and notice that the output reverts
to again include the \var{type} information.

\vspace{0.12in}
\noindent
The solution to this exercise is in Section \ref{sol_shapes_v5}. It 
simply shows the one line change to \var{SegListV4.h} to make the 
\var{getSpec()} function in the base class to be now virtual.
%-------------------------------------------+

%===================================================================
\newpage
\section{Solutions to Exercises}
%===================================================================

%===================================================================
\subsection{Solution to Exercise \ref{ex_shapes_v1}}
\label{sol_shapes_v1}
\input{sol_shapes_v1}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_shapes_v2}}
\label{sol_shapes_v2}
\input{sol_shapes_v2}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_shapes_v3}}
\label{sol_shapes_v3}
\input{sol_shapes_v3}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_shapes_v4}}
\label{sol_shapes_v4}
\input{sol_shapes_v4}

%===================================================================
\newpage
\subsection{Solution to Exercise \ref{ex_shapes_v5}}
\label{sol_shapes_v5}
\input{sol_shapes_v5}

%===================================================================
\newpage
\subsection{A Makefile for All Exercises in this Lab}
\label{sol_makefile}
\input{sol_makefile}

\end{document}

</pre></body></html>