You are on page 1of 6

C++ Primer

Laboratory and Computational Physics 3

Last compiled August 11, 2017

1
Content from:

https://www.cs.rochester.edu/
~nelson/courses/csc_173/review/CppPrimer.html

1 C++ Classes and structures


The support that C++ provides for Object Oriented Programming, (OOP), is concentrated in
the class notion. The class is the unit of data abstraction in C++. On the surface the class can
be viewed like a C struct. The class provides the programmer with a method to encapsulate,
i.e. hide, the state of the abstract data type (ADT) and specify the external interface for use
of the ADT.

Here is a simple class definition for a complex number data type. Features of the definition
are described in the sections that follow.

class Complex
{
private:
double re;
double im;

public:
Complex(float r,float i) {re = r; im = i;}
Complex(float r) {re = r;im =0;}
~Complex() {};

double Magnitude(); // calculate magnitude

double Real() {return re;} // return real part


inline double Imag(); // return imaginary part

Complex operator+(Complex b)
{return Complex(re + b.re,im + b.im);}

Complex operator=(Complex b)
{re = b.re;im = b.im; return *this;}
}

1.1 Class and Structure Members


Elements of a class or structure can not only be variables storing the state of the object, such
as re and im in Complex, but also functions that perform operations on objects of that type.
The functions can have parameters specified, such as with Complex in Complex which is a
special class member called a constructor. Note here the C++ support for polymorphism
by allowing function names to be overloaded with different parameters. The compiler will de-
termine the correct function to use based on the data type of the parameters in the function call.

2
Complex has two Complex constructors defined with different parameter lists. Code that is
part of a member function of a class, such as the code in Complex::Magnitude(), has access
to all members of the class directly. Within Complex::Magnitude references to re or im will
access the data members of that object.

Note that defining a class member function is exactly the same as a regular function except
that the function name is prefaced with class-name::. A class function member can also
be directly accessed inside of a class function which was done to get the imaginary part of the
complex number in Complex::Magnitude(). Class member functions that are very short can
be declared as inline functions. If code for the member function is defined within the class
definition, such as Complex::Real() it is assumed to be an inline function. Otherwise, the
function must be explicitly defined as inline and code provided outside of the class definition,
such as Complex::Imag().

1.2 Public, private, protected members


When defining a class the programmer can specify the level of access to members of the class
from outside of the class. The keywords private, public and protected define the levels of
access:

• Any members defined within a public label are accessible directly by any other data
type.

• Members within a private label are accessible only from within member functions of the
class.

• If some private members, either data or function members, must be available to other
classes these can be specified using the friend designation.

As with the scope of variables in your program, good practice dictates limiting access to
the data members of a class. If program code outside of the class definition must modify data
members provide a class function to do this.
Similarly, if code must access the data members of the class, define them as private and
provide public class functions to access the data. If no access designators are provided, all class
members default to being private. The original C struct has been enhanced in that it can now
define member functions as well as data. struct can be viewed as a class in which all members
are public. The protected keyword is used to allow derived classes to have access to some
class members that are not available as public. A derived class is a new class that inherits all
of the properties of the class from which it is derived and may add new features specific to this
new class. An example of this from a drawing program is that the programmer has defined a
base class called Object. From this base class other objects are derived such as Rectangle and
Circle. The are some aspects of the Object class that are shared by all objects. Each of the
new objects may add other features such as a specific technique for drawing itself or calculating
its area. If functions in this derived class need access to some of the base class’s non-public
members then those members can be declared protected. Alternatively, you could use the
friend keyword to explicitly specify which other classes get access to the private members. A
more detailed discussion of inheritance and derived classes is beyond the scope of this C++
primer.

3
1.3 Constructors/destructors and creating objects (“new” and “delete”)
C++ handles many of the details of memory allocation for objects. The programmer can have
explicit control over the operators performed when an object is created or destroyed. The
constructor function is called whenever an object is created and the destructor function is
called when the object is destroyed. The constructor is specified as a class function with the
same name as the class. The destructor function is the class name prefaced with a . The
class constructor function can be overloaded, as in the Complex class, to provide for different
method to create new objects in the class. There can only be one destructor specified. If either
constructors or destructors are not defined for the class then the compiler will substitute a
default function. A call to a class constructor issued by code generated by the compiler at
the beginning of an object’s lifetime. A call to the destructor is performed at the end of the
object’s lifetime. For example, consider the simple program below that uses the Complex class:

#include <stdio.h>
#include "Complex.h"

main()
{
Complex a(1.0,1.0);
Complex b(5.0);

printf("a real = %f a imaginary = %f\n",a.Real(),a.Imag());


printf("b real = %f b imaginary = %f\n",b.Real(),b.Imag());
}

In this program the two Complex variables a and b are automatically created when main()
starts executing. The compiler will determine the appropriate constructor to call based on the
parameters specified in the object creation. The data members are accessed using the structure
operator, “.”. When main finishes executing the destructor for all objects automatically
created in main will be called. In the case of the Complex class the destructor is an empty
function. Note the inclusion of the file stdio.h. This is necessary for the definition of the
printf function. It is also possible to directly create a new object. This process is similar to
the new operation in Pascal or malloc’ing an object in C. The C++ operator for creating a
new object is new. This will return a pointer to an object of the requested data type. This is
shown in a rewrite of the proceeding program to explicitly create the objects:
#include <stdio.h>
#include "Complex.h"

main()
{
Complex *a;
Complex *b = new Complex(5.0);

a = new Complex(1.0,1.0);

printf("a real = %f a imaginary = %f\n",a->Real(),a->Imag());


printf("b real = %f b imaginary = %f\n",b->Real(),b->Imag());

4
delete a;
delete b;
}

In this program the two complex objects are directly created using the new operator. Again
the compiler will determine the appropriate constructor to call based on the parameter sequence
given. Access to the class members is now via the structure reference operator, ->. Since these
objects were explicitly created, good coding practice dictates that the programmer explicitly
remove the objects when through with them. This is done using the delete operator. Again,
if there was a destructor function defined it would be called at this point.

1.4 Overloaded operators


C++ provides the capability to overload standard operators. This is a very useful feature if
there is a commonly accepted use for the operator. For example, complex mathematics defines
the addition of two complex numbers. It is appropriate to overload the + operator to provide
this for the Complex class. This class also overloads the assignment operator so that one
complex number can be assigned to another. These features are used in the following program:

#include <stdio.h>
#include "Complex.h"

main()
{
Complex a(1.0,1.0);
Complex b(5.0);
Complex c(0,0);

c = a + b;
printf("c real = %f c imaginary = %f\n",c.Real(),c.Imag());
}

The definitions for the overloaded assignment and addition operators each take only one
parameter. C++ in reality treats the overloaded operator as another function. The left hand
side of the operator is considered to be the current object. In the example above, this would be
the a. Writing a + b could have equivalently been written a.operator+(b). The overloaded
operators are defined within the class and are considered class member functions. Note that
direct access to the private data of the Complex object on the right hand side of the operator is
permitted is the operator+ function. Also, not the use of the keyword this in the assignment
function which corresponds to a pointer to the current object. The return statement references
this to return a value that is equal to what was stored in the left hand side of the assignment.

2 Include files
A part of standard OOP practice places the definition of a class and its inline class functions
into an include file. This file holds the definition of the external interface to the class. The
user of a class object has access to it through the public members of the class. This include file
must be specified at the beginning of any source code file that will manipulate objects of the

5
class. The standard file suffix is .h for include files. The following lines of code might appear
at the top of a source file that works with complex numbers:

#include <stream.h>
#include <stdlib.h>
#include "Complex.h"

This file will include three other files. It is as if the information contained in those three
files was directly typed into the source file. The C++ compiler provides include files for the
standard run time library functions that are used in C programs. The standard include files
are specified inside <>. This instructs the compiler to search for the files in the ”standard”
include file locations. If your program is using any functions from the run time library you
must include the appropriate files so that the compiler has a definition (return data type and
parameters) for these functions. Enclosing the include file name inside "" starts the file search
using the current directory and standard file reference mechanisms. You can specify the fully
qualified path name for the include file in this statement. If the file is not found and it was not
specified as a full path name then the search is continued in the standard places.

3 Using the compiler


The compiler we will use for this course is g++. There are not many command line options
that you should need. The basic compilation command is:

g++ -o executable-file source-files

This will create an executable program in the file you specify as executable-file. If there
are several source file that make up your program they can all be listed on the command line
separated by spaces.

You might also like