You are on page 1of 56

CSC 221: Object-Oriented Programming with C++

Lecture Note by
Dr. Oyelami M. O.
Comparison of Some Programming Paradigms
Paradig
m

Main
characteristics
(examples)

Description

Computation
as statements that di
Imperativ
rectly
change
a
e
program state (data
fields)

Direct assignments,
common data
structures, global
variables

Examples

C, C++, Java,PH
P, Python

A style of imperative
C, C++, Java
Structograms, indentat
Structure programming with
ion,
d
more logical program
no goto statements
structure
Derived
from
structured
programming, based
Procedur
on
the
concept
al
of modular
programming or
the procedure call
Eventdriven inc
luding ti
me
driven

Program
flow is
ActionScript
determined
mainly
Main
loop,
event
by
events,
such
handlers, asynchronou
as mouse
clicks or
s processes
interrupts
including
timer
Treats datafields as

Objectoriented

Local
variables,
sequence,
selection, iteration,
and modularization

C, C++, Lisp,
PHP, Python

Objects,
C++, C#,Eiffel,
methods, message
objects manipulated passing, information
Java,PHP, Pytho
through
pre- hiding,
data n, Ruby, Scala
1

Paradig
m

Main
characteristics
(examples)

Description

Examples

defined methods only abstraction, encapsulat


ion,polymorphism,inhe
ritance,serializationmarshalling
Fundamentals of Object-Oriented Design
Object Oriented Design (OOD) attempts to help with the
complexity of designing, writing, and maintaining software.
OOD includes the following concepts:
o Modularity: Modularity is a technique of composing
software from separate parts.
o Encapsulation: Encapsulation is a technique of hiding
implementation details, grouping them together.
o Abstraction: The process of separating ideas from
specific instances of those ideas at work.
It attempts to allow building of software by modeling realworld objects.

Features
1.
2.
3.
4.
5.
6.
7.

of

Object

Oriented

Object
Class
Data Hiding and Encapsulation
Dynamic Binding
Message Passing
Inheritance
Polymorphism
2

Programming

Object
o Object is a collection of number of entities. Objects take up
space in the memory. Objects are instances of classes.

Class
o Class is a collection of objects of similar type. Objects are
variables of the type class.
Encapsulation
o Combining data and functions into a single unit
called class and the process is known as Encapsulation
Abstraction
o Hiding the complexity of program is called Abstraction and
only essential features are represented.
Dynamic Binding
o Refers to linking of function call with function definition is
called binding and when it takes place at run time called
dynamic binding.
Message Passing
o The process by which one object can interact with other
object is called message passing.
Inheritance
o it is the process by which object of one class acquires the
properties or features of objects of another class.
3

Polymorphism
o A greek term means ability to take more than one form. An
operation may exhibit different behaviours in different
instances. The behaviour depends upon the types of data
used in the operation.

Windows Programming
o Windows programming generally involves developing a GUIbased program.
o Many high-level languages are well suited for GUI
development by hiding much of the programming complexity
using object oriented techniques.
C++
C++ is a general purpose programming language.
It is a superset of the C programming language and created by
Bjarne Stroustrup
The key concept in C++ is class. A class is a user-defined type
Structure of a C++ Program
//my first program in C++
#include <iostream>
using namespace std;
int main ()
{
cout << "Hello World!";
return 0;
}
Comments

Comments are parts of the source code disregarded by the


compiler. They simply do nothing.
Their purpose is only to allow the programmer to insert notes
or descriptions embedded within the source code.
C++ supports two ways to insert comments:

/* my second program in C++


with more comments */
#include <iostream>
using namespace std;
int main ()
{
cout << "Hello World! "; // prints Hello World!
cout << "I'm a C++ program"; // prints I'm a C++
program
return 0;
}
Data Types
We can manipulate in C++ programs two different categories
of types:
built-in types which are defined in the C++ compiler itself;
class type which are defined in C++ source code from the
built-in types.

Fundamental Data Types

Variable Naming Conventions


A variable identifier can be composed of letters, digits and
underscore character _.
It must begin with either a letter or an underscore.
Usually, one concatenates words to build long identifier either
using the under-score character - as a space, or by using
upper caps for first letter of each word (except the first letter):
A variable cannot contain a space and punctuation marks.
A variable cannot match any keyword of the C++ language nor
your compiler's specific ones, which are reserved keywords.
The standard reserved keywords are:
7

asm, auto, bool, break, case, catch, char, class, const,


const_cast,
continue,
default,
delete,
do,
double,
dynamic_cast, else, enum, explicit, export, extern, false,
float, for, friend, goto, if, inline, int, long, mutable,
namespace, new, operator, private, protected, public,
register, reinterpret_cast, return, short, signed, sizeof,
static, static_cast, struct, switch, template, this, throw,
true, try, typedef, typeid, typename, union, unsigned,
using, virtual, void, volatile, wchar_t, while
Declaration of Variables
In order to use a variable in C++, we must first declare it
specifying which data type we want it to be.
Examples

Initialization of Variables
Syntax: type identifier = initial_value;
Example: int a = 0;

// initialization of variables
#include <iostream>
using namespace std;
int main ()
{
int a=5; // initial value = 5
int b(2); // initial value = 2
8

int result; // initial value


undetermined
a = a + 3;
result = a - b;
cout << result;
return 0;
}
Scopes of Variables
A variable can be either of global or local scope.
A global variable is a variable declared in the main body of the
source code, outside all functions, while a local variable is one
declared within the body of a function or a block.

Global variables can be referred from anywhere in the code,


even inside functions, whenever it is after its declaration.
Roughly, a identifier can be used everywhere from its
declaration point to the end of the block defined by a couple of
{ }.
#include <iostream>
using namespace std;
int main()
{
int i;
i = 3;
if(i == 3) {
9

int j;
j = i + 4;
}
j = i + 3;
}
Variables can also be declared in the for statement.
In that case the scope of the identifier is the loop :
int main()
{
int j;
j = 0;
for(int i = 0; i < 10; i++) j = j + i;
}

Basic Input/Output
The standard C++ library includes the header file iostream,
where the standard input and output stream objects are
declared.
Standard Output (cout)
By default, the standard output of a program is the screen,
and the C++ stream object defined to access it is cout.
cout is used in conjunction with the insertion operator,
which is written as << (two "less than" signs).

10

The insertion operator (<<) may be used more than once in a


single statement:
cout << "Hello, " << "I am " << "a C++ statement";
In C++, a new-line character can be specified as \n or endl

Standard Input (cin).


Handling the standard input in C++ is done by applying the
overloaded operator of extraction (>>) on the cin stream.
The operator must be followed by the variable that will store
the data that is going to be extracted from the stream. For
example:

Strings
Variables that can store non-numerical values that are longer
than one single character are known as strings.

11

The C++ language library provides support for strings through


the standard string class.
This is not a fundamental type, but it behaves in a similar way
as fundamental types do in its most basic usage.
// my first string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string mystring = "This is a string";
cout << mystring;
return 0;
}
Constants
Constants are expressions with a fixed value.
Literals
Literals are used to express particular values within the source
code of a program.
Literal constants can be divided in Integer Numerals, FloatingPoint Numerals, Characters, Strings and Boolean Values.
Examples
5=5; //5 is a literal constant
75 // decimal
0113 // octal
0x4b // hexadecimal
75 // int
75u // unsigned int
75l // long
75ul // unsigned long
12

Floating Point Numbers


They express numbers with decimals and/or exponents.
3.14159 // 3.14159
6.02e23 // 6.02 x 10^23
1.6e-19 // 1.6 x 10^-19
3.0 // 3.0
3.14159L // long double
6.02e23f // float
Character and String Literals
'z'
'p'
"Hello world"
"How do you do?"
Escape Codes
These are characters that are impossible to express otherwise
in the source code of a program.

13

Boolean Literals
There are only two valid Boolean values: true and false.
These can be expressed in C++ as values of type bool by
using the Boolean literals true and false.
Declared Constants (const)
With the const prefix you can declare constants with a specific
type in the same way as you would do with a variable:
const int pathwidth = 100;

14

Defined Constants (#define)


You can define your own names for constants that you use
very often without having to resort to memory consuming
variables, simply by using the #define preprocessor directive.
Its format is:
#define identifier value
For example:
#define PI 3.14159
#define NEWLINE '\n'
Expressions
An expression is a sequence of one or more operands, and zero
or more operators, that when combined, produce a value.
For example:
x-3
cos(y) + y
x+y+z
x <= y * 7 - 2
Arithmetic Operators
List of operators
The standard mathematic
arithmetic expressions

symbols

15

can

be

used

to

write

The % computes the reminder of an integer division (for


instance 17 % 5 has the value 2) ; the result is well defined
only if both operands are positive.
All those operators but % can be used with either integer or
floating point operands.
Operators Depend on the Types of the Operands
Internally, each symbol corresponds to different operations,
depending with the type of the operands:
#include <iostream>
using namespace std;
int main()
{
cout << 15 / 4 << << 15.0 / 4.0 << \n;
}
displays 3

3.75.

16

Implicit Conversions
Basically operators are defined for two operands of the same
type. The compiler can automatically convert a numerical type
into another one so that the operator exists:
#include <iostream>
using namespace std;
int main()
{
cout << 3 + 4.3 << \n;
}
result is 7.3
The implicit conversion cannot be done to a type that loses
information (i.e. double to int for instance).
For example the % operators is only defined for integer
operands :
#include <iostream>
using namespace std;
int main()
{
cout << 3.0%4.0 << \n;
}
Boolean Operators
We can define more precisely what we called a condition in the
description of the if, for, and while syntax.
It is a boolean expression, which is an expression whose value
is of type bool.

17

A few operators have a boolean value and takes boolean


operands:

#include <iostream>
using namespace std;
int main() {
bool c1, c2;
c1 = true;
c2 = !c1 && false;
cout << c1 << << c2 << \n;
}
The compiler is smart and will compute the value of the second
operand of a boolean operation only if this is necessary.
Comparison Operators
The comparison operators take two numerical operands and
have a Boolean value:
18

The equality and inequality are defined for any types and
return a Boolean value:

Assignment Operator
A strange thing in C++ is that assignments are also
expressions:
j = 3 + (i = 5);
is legal, and will assign to i the value 5, and to j the value 8.
But feel free not to use such weird tricks.
19

Compound Assignment (+=, -=, *=, /=, %=, >>=, <<=,


&=, ^=, |=)
When we want to modify the value of a variable by performing
an operation on the value currently stored in that variable, we
can use compound assignment operators:

// compound assignment operators


#include <iostream>
using namespace std;
int main ()
{
int a, b=3;
a = b;
a+=2; // equivalent to a=a+2
cout << a;
return 0;
}

20

Increase and decrease (++, --)


c++;
c+=1;
c=c+1;
are all equivalent

Precedence of Operators
The precedence of operators is the order used to evaluate
them during the evaluation of the complete expression.
To be compliant with the usual mathematical notations, the
evaluation is not left-to-right.
For example 3 + 4 * 5 + 6 * 7 is considered by the compiler as
3 + (4 * 5) + (6 * 7) and NOT AS (((3 + 4) * 5) + 6) * 7
When two operators have same precedence (i.e. when we have
the same operator twice), the evaluation is left-to-right
From greatest to lowest priority, the priority order is as
follows:

21

22

Control Structures
Control structures help a program to branch, repeat code or
take decisions instead of linear execution of instructions.
Conditional Statement
The if statement
The if statement executes a part of a program only if a given
condition is
if(condition)
<statement to execute if the condition is true>
or
23

if (condition)
<statement to execute if the condition is true>
else
<statement to execute if the condition is false>
A statement here is either a part of a program enclosed in { },
or a single line terminated with a ;.
For example :
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if(n < 0) n = 0;
else {
n = 2 * n;
n = n - 1;
}
cout << n << \n;
system("pause");
}
Loops
Loops have as purpose to repeat a statement a certain number
of times or while a condition is fulfilled.
The for statement
The for statement repeats the execution of a part of a
program.
for(initialization; condition; increment)
<statement to repeat>
24

For example, to display all positive integers strictly smaller


than a value given by the user :
#include <iostream>
using namespace std;
int main()
{
int n, k;
cin >> n;
for(k = 0; k < n; k++) cout << k << \n;
system(pause);
}
The while statement
The while statement repeats the execution of a statement as
long as a condition is true.
For instance:
#include <iostream>
using namespace std;
int main()
{
double a, b, c;
a = 0.0; b = 2.0;
while(b-a > 1e-9) {
c = (a+b)/2.0;
if(c*c - 2.0 > 0.0) b = c; else a = c;
}
cout << c << \n;
system(pause);
}
25

The do { } while statement


Similar to while, but the statement is always executed at least
once.
#include <iostream>
using namespace std;
double a, b, c;
a = 0.0; b = 2.0;
do {
c = (a+b)/2.0;
if(c*c - 2.0 > 0.0) b = c; else a = c;
} while(fabs(c*c - 2.0) > 1e-4);
cout << c << \n;
system(pause);
}
The continue statement
The continue statement forces the current execution of the
loop to stop.
It is equivalent to jump to the end of the statement, so that
the next iteration can start:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
for(int n = 0; n<6; n++)
{
cout << "n = " << n << \n;
if(n%2 == 1) continue;
cout << "This is even\n";
system(pause);
}
}
26

The break Statement


Using break we can leave a loop even if the condition for its
end is not fulfilled.
// break loop example
#include <iostream>
using namespace std;
int main ()
{
int n;
for (n=10; n>0; n--)
{
cout << n << ", ";
if (n==3)
{
cout << "countdown aborted!";
break;
}
}
return 0;
}
The switch / case Statements
When the behaviour of the program can be organized as a
succession of separate cases, selected by an integer value, the
switch statement is more efficient and elegant than a
succession of if :
#include <iostream>
using namespace std;
int main()
{
int k;
cout << "Enter a value between 1 and 3 : ";
cin >> k;
27

switch(k)
{
case 1:
cout << "one!\n";
break;
case 2:
cout << "two!\n";
break;
case 3:
cout << "three!\n";
break;
default:
cout << "Didnt get it, did you ?\n";
break;
system(pause);
}
}
Functions
Using functions we can structure our programs in a more
modular way, accessing all the potential that structured
programming can offer to us in C++.
A function is a group of statements that is executed when it is
called from some point of the program. The following is its
format:
type name ( parameter1, parameter2, ...)
{
Statements
}
where:
type is the data type specifier of the data returned by the
function.
name is the identifier by which it will be possible to call the
function.
28

parameters: Each parameter consists of a data type specifier


followed by an identifier, like any regular variable declaration
statements is the function's body. It is a block of statements
surrounded by braces { }.
// function example
#include <iostream>
using namespace std;
int addition (int a, int b)
{
int r;
r=a+b;
return (r);
}
int main ()
{
int z;
z = addition (5,3);
cout << "The result is " << z;
system(pause);
return 0;
}
Functions with no Type

A function that returns no value is of type void


// void function example
#include <iostream>
using namespace std;
void printmessage ()
{
cout << "I'm a function!";
}
int main ()
{
printmessage ();
system(pause);
29

return 0;
}
Passing Arguments by Reference
// passing parameters by reference
#include <iostream>
using namespace std;
void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
}
int main ()
{
int x=1, y=3, z=7;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z;
return 0;
}
Default Values in Parameters

When declaring a function we can specify a default value for


each of the last parameters.
This value will be used if the corresponding argument is left
blank when calling to the function.
// default values in functions
#include <iostream>
using namespace std;
int divide (int a, int b=2)
{
int r;
r=a/b;
return (r);
30

}
int main ()
{
cout << divide (12);
cout << endl;
cout << divide (20,4);
system(pause);
return 0;
}
Overloaded Functions

In C++ two different functions can have the same name if


their parameter types or number are different.
// overloaded function
#include <iostream>
using namespace std;
int operate (int a, int b)
{
return (a*b);
}
float operate (float a, float b)
{
return (a/b);
}
int main ()
{
int x=5,y=2;
float n=5.0,m=2.0;
cout << operate (x,y);
cout << "\n";
cout << operate (n,m);
cout << "\n";
return 0;
}
31

Inline Functions

Inline specifier is used to suggest to the compiler that the


code generated by the function body is inserted at each
point the function is called, instead of being inserted only
once and perform a regular call to it, which generally
involves some additional overhead.
The format for its declaration is:
inline typename ( arguments ... ) { instructions ... }
Recursivity

Recursivity is the ability of a function to call itself.


Therefore, a recursive function is a function that contains a statement or
statements that make a call to itself.

A recursive function calls itself and looks like what is shown below:
function( )
{
function( );
}

Recursion is of two types:

i.

Direct Recursion

ii.

Indirect Recursion

In direct recursion, a function a calls itself. That is, its code contains a call to
itself while in indirect recursion, the function a calls function b, b calls
another function c and so on until a is called again.
Of necessity, a good recursive function must have the following components:
i.

A test to stop or continue the recursion

ii.

A recursive call that continues the recursion

iii.

An end case that stops the recursion


32

Consider the recursive function below:


Int add( int m)
{
if (m==1) // test to stop or continue
return 1; // end case: stopping recursion
else
return m + add(m 1); // recursive call that continues the
recursion
}
Consider another function recursion below:
void recursion(argumentlist)
{
statement1;
if(test)
recursion(arguments);
statement2;
}

As long as the if statement remains true, each call to recursion( )

executes statement1, then invokes a new incarnation of recursion( ) without


reaching statement2

When the if statement becomes false, the current call then proceeds to

statement2.Then, when the current call terminates, the program control


returns to the previous version of recursion( ) that called it. Then that
version of recursion( ) completes executing its statement2 section and
terminates, returning control to the prior call, and so on.
Example:
To obtain the factorial of a number (n!) the mathematical formula would
be: n! = n * (n-1) * (n-2) * (n-3) ... * 1
More concretely, 5! (factorial of 5) would be: 5! = 5 * 4 * 3 * 2 * 1 =
120
A recursive function to calculate this in C++ could be:

33

// factorial calculator
#include <iostream>
using namespace std;
long factorial (long a)
{
if (a > 1)
return (a * factorial (a-1));
else
return (1);
}
int main ()
{
long number;
cout << "Please type a number: ";
cin >> number;
cout << number << "! = " << factorial (number);
return 0;
}

Function Prototype
To be able to call a function, it must have been declared in
some earlier point of the code.
Function prototyping allows you to do this.
// declaring functions prototypes
#include <iostream>
using namespace std;
void odd (int a);
void even (int a);
int main ()
{
int i;
do {
cout << "Type a number (0 to exit): ";
cin >> i;
odd (i);
} while (i!=0);
34

return 0;
}
void odd (int a)
{
if ((a%2)!=0) cout << "Number is odd.\n";
else even (a);
}
void even (int a)
{
if ((a%2)==0) cout << "Number is even.\n";
else odd (a);
}
Arrays
An array is a series of elements of the same type placed in
contiguous memory locations that can be individually
referenced by adding an index to a unique identifier.
For example, an array to contain 5 integer values of type int
called billy could be represented like this:

A typical declaration for an array in C++ is:


type name[elements];
Example: int main[23];
Initializing Arrays

When declaring a regular array of local scope (within a


function, for example), if we do not specify otherwise, its
elements will not be initialized to any value by default.
35

Example:
int billy [5] = { 16, 2, 77, 40, 12071 };
Accessing the Values of an Array

The syntax is: name[index]


billy[2] = 75;
a = billy[2];
Some other valid operations with arrays:
billy[0] = a;
billy[a] = 75;
b = billy [a+2];
billy[billy[a]] = billy[2] + 5;
// arrays example
#include <iostream>
using namespace std;
int billy [] = {16, 2, 77, 40, 12071};
int n, result=0;
int main ()
{
for ( n=0 ; n<5 ; n++ )
{
result += billy[n];
}
cout << result;
return 0;
system(pause);
}

36

Multidimensional Array
Multidimensional arrays can be described as "arrays of
arrays".
For example, a bidimensional array can be imagined as a
bidimensional table made of elements, all of them of a same
uniform data type.

#include<iostream>
using namespace std;
#define WIDTH 2
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
{
for (m=0;m<WIDTH;m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
}
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
cout<<jimmy[n][m]<<"\v";
}
system("pause");
return 0;
}

37

Arrays as Parameters

The name of an array is the address of the first element of the


array.
// arrays as parameters
#include <iostream>
using namespace std;
void printarray (int arg[], int length)
{
for (int n=0; n<length; n++)
cout << arg[n] << " ";
cout << "n";
}
int main ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray (secondarray,5);
system(pause);
return 0;
}
Structures

Structure is a group of data elements grouped together under one name.


These data elements, known as members, can have different types and
different lengths.
Structures are declared in C++ using the following syntax:

struct structure_name
{
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
38

.
.
} object_names;

Where structure_name is a name for the structure type, object_name


can be a set of valid identifiers for objects that have the type of this
structure.
Within braces { } there is a list with the data members, each one is
specified with a type and a valid identifier as its name.
Structure variables can also be created as below:

struct product {
int weight;
float price;
};
product apple;
product banana, melon;
// structur.cpp -- a simple structure
#include <iostream>
#include <string>
using namespace std;
struct student // structure declaration
{
string name, sex;
short age;
};
int main()
{
student John;
cout << Enter Your Name \n;
cin>>John.name;
cout << Enter Your Sex \n;
cin>>John.sex;
cout << Enter Your Age \n;
cin>>John.age;
//output students particulars
cout << Your name is <<John.name<<\n;
cout << Your sex is <<John.sex<<\n;
39

cout << Your age is <<John.age<<\n;


system(pause);
return 0;
}

An Overview of Pointers
Pointers are variables that store addresses of values.
Reference operator (&)

The address that locates a variable within memory is what we call a


reference to that variable.
This reference to a variable can be obtained by preceding the identifier of
a variable with an ampersand sign (&), known as reference operator, and
which can be literally translated as "address of".
For example: ted = &andy; would assign to ted the address of variable
andy,

The listing below shows how to find the addresses of variables:


#include <iostream>
using namespace std;
int main(void)
{
int donuts=6;
double cups=4.5;
cout<<donuts value = <<donuts<<\n;
cout<<donuts address = <<&donuts<<\n;
system(pause);
return 0;
}
Dereferencing Pointers

40

Dereferencing a pointer means referring to the pointed-to


value. To dereference a pointer, apply the dereferencing
operator (*) to it.
Listing 2
#include <iostream>
using namespace std;
int main(void)
{
int updates=6;
int *p_updates;
p_updates=&updates;
cout<<* p_updates<<\n;
return 0;
}
*p_updates and updates are equivalent. We can assign values
to *p_updates as below:
*p_updates=* p_updates + 1;

Pointers and Numbers


Pointers are not integer types, even though computers
typically handle addresses as integers.
Integers are numbers you can add, subtract, divide, etc. but
a pointer describes a location, and it doesnt make sense to
multiply two locations.
In terms of operations you can perform with them, pointers
and integers are different from each other.
You cant assign an integer to a pointer as below:
int *pi;

41

pi=ox8566fff4; // type mismatch


Although you may know that ox8566fff4 is a combined
segment offset address, nothing in the statement tells the
program that this number is an address.
To correct that you should have the following:
int *pi;
pi=(int *)ox8566fff4;

Allocating Memory With New


To allocate memory at run-time instead of at compile time,
you use the new operator.
You tell the new operator what data type you want memory
for: new finds a block of memory of the correct size and
returns the address of the block. It assigns this address to a
pointer. It uses the type to figure out how many bytes are
needed. The syntax is:
type * poniter_name = new type
Listing 3
The listing below shows how to create memory with new:
#include<iostream>
using namespace std;
int main(void)
{
int *pi=new int; // allocate a space for an int
*pi=1001;
cout<<"int value="<<*pi<<"location=" << pi<<"\n";
double *pd=new double;
*pd=100001.2;
cout<<"double value ="<<*pd<<"location: "<<pd<<"\n";
42

cout<<"sizeof pi="<<sizeof pi<<"\n";


cout<<"sizeof pd="<<sizeof pd<<"\n";
system(pause);
return 0;
}
Note: When a computer does not have enough memory to satisfy
a request for a new memory, new returns the value 0. A pointer
with a value 0 is called a null pointer. It doesnt point to any
valid data.
Using new to Create Dynamic Arrays
Static Binding: The space for any array declared is allocated at
compile time. Whether or not the program finally uses the array,
the array is there, using up memory. This is called static binding,
meaning that the array is built into the program at compilation
time.
Dynamic Binding: When memory is requested during run-time,
this is called dynamic binding.
The syntax for allocating and assigning memory for an array with
new is:
type_name
*pointer_name
type_name[num_elements];

new

This returns
a block of memory large enough to hold
num_elements elements of the type type_name, with
pointer_name pointing to the first element.
Example
int* psome= new int[10];
psome points to the first element of the array. Alternatively, the
elements can be accessed as psome[0], psome[1], psome[9].
43

A fundamental difference between a pointer and an array name is


that you cant change the value of an array name, but a pointer is
a variable and hence, you can change its value.
Listing 4
#include<iostream>
using namespace std;
int main(void)
{
double *p3=new double[3];
p3[0]=0.2;p3[1]=0.5;p3[2]=0.8;
cout<< "p3[1] is"<<p3[1]<<"\n";
p3=p3+1;
cout<<"Now p3[0] is"<<p3[0]<<"\n";
double *pd=new double;
*pd=100001.2;
cout<<"double value ="<<*pd<<"location: "<<pd<<"\n";
system(pause);
return 0;
}
The output :
P3[1] is 0.5
Now p3[0] is 0.5

Creating Dynamic Structures With new


Using new with structures has two parts:
1. Creating the structure
2. Accessing its members
To create a dynamic structure, use the syntax:
type *pointer = new type;
44

For example, to create an unnamed structure of the inflatable


type and to assign its address to a suitable pointer, do the
following:
inflatable *ps = new inflatable;
To access the structure members, you cant use the dot
membership operator with the structure name because the
structure has no name. All you have is its address. To access the
members, you have to use the arrow membership operator (->).
Example
Consider the following:
struct things
{
int good;
int bad;
};
things grubnose={3, 453};
things* pt=&grubnose;
Use the . operator with the structure name: grubnose.good and
grubnose.bad
Use -> operator with pointer-to-structure:
pt->good and pt->bad
Another approach to reference the structure members is to say
that if ps is a pointer to a structure, then *ps represents the
pointed-to value, the structure itself. Then, because *pt is a
structure, (*pt).good is the good member of the structure.
The listing below uses new to create an unnamed structure
and demonstrates both pointer notations for accessing
structure members.
45

Listing 5
// structur.cpp -- a simple structure allocated using new
#include <iostream>
#include <string>
using namespace std;
struct student // structure declaration
{
string name, sex;
short age;
};
int main()
{
student* variable=new student;
cout << Enter Your Name \n;
cin>>variable->.name;
cout << Enter Your Sex \n;
cin>>variable->.sex;
cout << Enter Your Age \n;
cin>>(*variable).age;
//output students particulars
cout << Your name is <<variable->name<<\n;
cout << Your sex is <<variable->sex<<\n;
cout << Your age is <<variable->age<<\n;
system(pause);
return 0;
}

Freeing Memory with delete


Using new to request for memory when you need it is just the
more glamorous half of the C++ memory management package.
46

The other half is the delete operator, which lets you return
memory to the memory pool when you are finished with it. The
memory that you return or free can be reused by other parts of
your program.
You use delete by following it with a pointer to a block of
memory originally allocated with new:
int *ps=new int;
delete ps;
Note: You cannot use delete to free memory created by declaring
variables.
int jugs =5;

// ok

int* pi =&jugs //ok


delete pi;

//not allowed, pi not allocated by new

You can use another pointer to free memory allocated with


another pointer:
int * ps= new int;

// allocate memory

int * pq= ps;

// set second pointer to the same block

delete pq;

//delete with second pointer

Listing 6
#include<iostream.h>
#include<string.h>
char* getname (void);
// function prototype
int main(void)
{
char* name; // create a pointer to no storage
name=getname(); // assign address of string to name
cout<<name <<at <<(int*) name<<\n;
delete name; // memory freed
name=getname(); // reuse freed memory
47

cout<<name<< at << (int*)name<<\n;


return 0;
}
char* getname(void)
{
char name[100];
cout<<Enter your name\n;
cin>>name;
return name;
}
Review Questions
1. Suppose ted is a double variable. Declare a pointer that
points to ted, and use the pointer to display teds value.
2. Write a code fragment that asks the user to enter a positive
integer and then creates a dynamic array of that many ints.
3. Is the following valid code? If so, what does it print?
cout <<(int*) Home of the jolly bytes;
Pointer Arithmetic

Only addition and subtraction operations are allowed to be


conducted with pointers.
Suppose that we define three pointers as:
char *mychar;
short *myshort;
long *mylong;
Suppose we know that they point to memory locations 1000,
2000 and 3000 respectively.
Assuming that in a given compiler for a specific machine, char
takes 1 byte, short takes 2 bytes and long takes 4.
If we write:
mychar++;
myshort++;
48

mylong++;
mychar, would contain the value 1001.
myshort would contain the value 2002
mylong would contain 3004

Void Pointers

Void pointers are pointers that point to a value that has no


type.
One of its uses may be to pass generic parameters to a
function:
// increaser
#include <iostream>
using namespace std;
void increase (void* data, int psize)
{
if ( psize == sizeof(char) )
{ char* pchar; pchar=(char*)data; ++(*pchar); }
else if (psize == sizeof(int) )
{ int* pint; pint=(int*)data; ++(*pint); }
}
49

int main ()
{
char a = 'x';
int b = 1602;
increase (&a,sizeof(a));
increase (&b,sizeof(b));
cout << a << ", " << b << endl;
return 0;
}
Null Pointer

A null pointer is a regular pointer of any pointer type which has a special
value that indicates that it is not pointing to any valid reference or
memory address:

int * p;
p = 0; // p has a null pointer value
Other Data Types
1. Defined data types (typedef)
C++ allows the definition of our own types based on other
existing data types. We can do this using the keyword typedef,
whose format is:

typedef existing_type new_type_name ;


where existing_type is a C++ fundamental or compound type and
new_type_name is the name for the new type we are defining.
For example:
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50]
50

We can use the defined types in other declarations as below:


C mychar, anotherchar, *ptc1;
WORD myword;
pChar ptc2;
field name;
2. Unions
A union is a data format that can hold different data types but
only one type at a time.
That is, whereas a structure can hold, say, an int and a long
and a double, a union can hold an int or a long or a double.
Syntax:
union union_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;
Example
union one4all
{
int int_val;
long long_val;
double double_val;
};
You can use a one4all variable to hold an int, a long, or a double, just as long
as you do so at different times:
one4all pail;
pail.int_val = 15; // store an int
cout << pail.int_val;
pail.double_val = 1.38; // store a double, int value is lost
cout << pail.double_val;
51

3. Enumerations

Enumerations create new data types to contain something different that


is not limited to the values fundamental data types may take.

Its syntax is:

enum enumeration_name
{
value1,
value2,
value3,
.
.
} object_names;
Example:
enum colors_t {black, blue, green, cyan, red, purple, yellow, white};
colors_t mycolor;
mycolor = blue;

Enumerations constants are always assigned an integer numerical value


internally.
If it is not specified, the integer value equivalent to the first possible
value is equivalent to 0 and the following ones follow a +1 progression.
We can explicitly specify an integer value for any of the constant values
that our enumerated type can take:

enum months_t { january=1, february, march, april,may, june, july, august,


september, october, november, december} y2k;

Classes
A class is an expanded concept of a structure: instead of
holding only data, it can hold both data and functions.
An object is an instantiation of a class. In terms of variables, a
class would be the type, and an object would be the variable.
Classes are generally declared using the keyword class, with
the following format:
52

int * p;
p = 0; // p has a null pointer value

class class_name
{
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;
class_name is a valid identifier for the class
object_names is an optional list of names for objects of this
class.
The body of the declaration can contain members, that can be
either data or function declarations, and optionally access
specifiers.
An access specifier is one of the following three keywords:
private, public or protected.
private members of a class are accessible only from within
other members of the same class or from their friends.
protected members are accessible from members of their same
class and from their friends, but also from members of their
derived classes.
public members are accessible from anywhere where the
object is visible.
By default, all members of a class declared with the class
keyword have private access for all its members.
Example
class CRectangle
{
int x, y;
53

public:
void set_values (int,int);
int area (void);
} rect;
You invoke a class member function, or method, by using a class object. You
do so by using the dot membership operator:
rect.set_values (3,4);
myarea = rect.area();
Here is the complete example of class CRectangle:
// classes example
#include <iostream>
using namespace std;
class CRectangle
{
int x, y;
public:
void set_values (int,int);
int area ()
{
return (x*y);
}
};
void CRectangle::set_values (int a, int b)
{
x = a;
y = b;
}
int main ()
{
CRectangle rect;
rect.set_values (3,4);
54

cout << "area: " << rect.area();


return 0;
}
The scope operator (::) specifies the class to which the
member being declared belongs.
Constructors and Destructors

Constructors are used to initialize member variables or assign


dynamic memory during their process of creation of objects.
Constructors are automatically called whenever a new object of
this class is created.
A constructor function must have the same name as the class,
and cannot have any return type; not even void.
Constructors cannot be called explicitly as if they were regular
member functions. They are only executed when a new object
of that class is created
Constructor Example
// example: class constructor
#include <iostream>
using namespace std;
class CRectangle
{
int width, height;
public:
CRectangle (int,int);
int area () {return (width*height);}
};
CRectangle::CRectangle (int a, int b)
{
width = a;
height = b;
}
55

int main (){


CRectangle rect (3,4);
CRectangle rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}

56

You might also like