0% found this document useful (0 votes)
14 views34 pages

00 Pointers

Pointers are used to store the addresses of other objects in memory. They allow programs to dynamically allocate and access memory locations. Pointers contain the address of the object they are pointing to. Pointer arithmetic allows pointers to be incremented or decremented to access other memory addresses based on the pointer's data type size. Pointers can also be passed as parameters to functions, allowing the function to modify the pointer's referenced object.

Uploaded by

aqatanani440
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views34 pages

00 Pointers

Pointers are used to store the addresses of other objects in memory. They allow programs to dynamically allocate and access memory locations. Pointers contain the address of the object they are pointing to. Pointer arithmetic allows pointers to be incremented or decremented to access other memory addresses based on the pointer's data type size. Pointers can also be passed as parameters to functions, allowing the function to modify the pointer's referenced object.

Uploaded by

aqatanani440
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

OOP Course Al-Balqa Applied

Unviversity

POINTERS
1. C and C++ pointers are scalar types that store addresses of other objects
(variables)--they point to other objects. Pointers are usually used in
combination with memory management operations that allocate memory when
it is needed and release that memory when it is no longer needed, e.g. string
objects that may grow or shrink in length while the program is executing.

2. Because C and C++ have the capability to access specific memory locations
via pointers, it is an appropriate language for writing operating systems.

3. Data objects are stored or retrieved through pointers if declared with *


between the type-name and the identifier. The * can be anywhere between
type-name and identifier but is usually connected to the identifier.

type-name *identifier;

a) After the following declaration, the pointer named intPtr may store the
address of any int object. Currently, the pointer intPtr has not been
assigned a value (address).

int *intPtr; // declares a pointer to type integer

4. A pointer may have or may obtain one of these values:


a) It may be undefined (garbage).
b) It may contain the special pointer value 0 (known as NULL), an
address signifying a pointer to nothing.
intPtr = 0; // intPtr points to nothing
// could also code intPtr = NULL;
c) It may point to some object in memory.

1
OOP Course Al-Balqa Applied
Unviversity

POINTERS (CONTINUED)

5. Because pointers store addresses, their values become visually more


meaningful when written in a box with an arrow pointing to the object.

int anInt; // allocate space for an int object


anInt = 123; // direct addressing
int *p; // allocate space to store the address of an int object

123
anInt

p ?

6. When the pointer is assigned an address, the arrow points to the object stored
at the address. Pointers may be assigned values through the & operator,
which is called the address of operator. The address of operator returns the
address of its operand.

& object-name

a) The following statement stores the address of anInt into the pointer p
(the expression &anInt is read as "address of anInt"):

p = &anInt; // &anInt returns the memory location (address) of anInt

123
anInt

address
p of anInt

2
OOP Course Al-Balqa Applied
Unviversity

POINTERS (CONTINUED)

7. The value of the object pointed to by a pointer can also be altered indirectly.
The contents of anInt can be changed without even using anInt's name.
Indirect addressing with the dereference, or indirection, operator *, allows
inspection or change of the contents of memory pointed to by the pointer.

*p = -654; // indirect addressing stores -654 into anInt


// because p is pointing to anInt

-654
anInt

address
p of anInt

8. The syntax *p has two different meanings:


a) If it is preceded by a data type in a declaration (e.g. int *p;), it signifies
the declaration of a pointer to that data type.
b) In any other context, it is the dereference operator and signifies the
contents of the variable to which the pointer is pointing.

9. The term double indirection applies to pointers to pointers.

3
OOP Course Al-Balqa Applied
Unviversity

POINTERS (CONTINUED)

// Interchange two pointer values. The pointers are


// switched to point to the other's original int objects.
#include <iostream.h>

int main()
{
double *p1, *p2, *temp; // Three *s means 3 pointer objects
double n1, n2;

// Initialize the int objects


n1 = 99.9;
n2 = 88.8;
// Let p1 point to n1 and p2 point to n2
p1 = &n1;
p2 = &n2;
cout << "*p1 and *p2 before switch" << endl;
cout << *p1 << " " << *p2 << endl;

// Let p1 point to where p2 is pointing and


// let p2 point to where p1 is pointing to
temp = p1;
p1 = p2;
p2 = temp;

// Now the values of the pointers are switched to point


// to each other's int object. The ints do not move.
cout << "*p1 and *p2 after switch" << endl;
cout << *p1 << " " << *p2 << endl;
return 0;
}

Output is:
*p1 and *p2 before switch
99.9 88.8
*p1 and *p2 after switch
88.8 99.9

4
OOP Course Al-Balqa Applied
Unviversity

POINTER ARITHMETIC

1. Pointer arithmetic allows operations that either combine two pointers or


combine a pointer and integer.

2. When adding 1 to a variable of pointer type, you are actually changing the
address contained in the pointer to point to the next variable in memory of
that particular type.

3. If p is a pointer to type integer, then p += 1 advances p to the address of the


next integer in memory. Because p is declared as int *p, the compiler knows
p addresses variables of type int. The compiler also knows the size of an int
variable. Assuming the size of an int is 2 bytes, the compiler simply adds 2 to
p's address value. p += 10 advances p 10 units (20 bytes) from its present
position. p -= 2 moves p back 2 units (4 bytes).

4. Dereferencing has higher precedence than the increment operator. If p was


declared as int *p and assigned an address of an integer variable, then cout
<< *p++ << endl; would first print the value addressed by p, then the
increment operator ++ would advance p to the next integer in memory.

5. It is possible for pointer arithmetic to cause pointers to point to incorrect


types in memory. In the expression ++floatptr, the value of floatptr would be
incremented by sizeof (float). If type float occupied 4 bytes in memory, 4
would be added to the address contained in floatptr. It is possible that the
variable stored at the new address may not be of type float, which could
cause problems because floatptr assumes that it is pointing to a variable of
type float.

6. When doing arithmetic operations involving two pointers:

a) The expression
k = floatptr1 - floatptr2;
defines k such that
floatptr2 + k == floatptr1

b) The following is not a legitimate expression:

floatptr1 + floatptr2

5
OOP Course Al-Balqa Applied
Unviversity

POINTER ARITHMETIC (CONTINUED)

/* address3.cpp
*
* Synopsis - Uses pointers to print the addresses of a char
* variable and an int variable and the address of
* the next available memory location for each
* data type.
*
* Objective - Illustrates what is meant by a pointer-to-int
* being a separate data type. Demonstrates syntax
* of declaring a pointer-to-char variable,
* initialization of pointer variables, and
* the result of adding 1 to pointer variables
* of different types.
*/

// Include Files
#include <iostream.h>

void main( void )


{
int intvar, *int_ptr; // declares an int and a pointer to an int
char charvar, *char_ptr = &charvar; // declares a char and a pointer to
// a char. Initializes char_ptr

int_ptr = &intvar;

cout << "The address of charvar is " << char_ptr << endl;
cout << "The next character could be stored at "
<< (char_ptr + 1) << endl; // references the next potential
// address of a char

cout << "The address of intvar is " << int_ptr << endl;
cout << "The next integer could be stored at "
<< (int_ptr + 1) << endl; // references the next potential
// address of an int
}

6
OOP Course Al-Balqa Applied
Unviversity

POINTERS AS FUNCTION PARAMETERS

1. Most languages have two basic methods of passing parameters to


subprograms:

a) Passing by value - a copy is made of the current value of the


parameter. The function will operate on the copy. The original
parameter will not be changed by the subprogram.

b) Passing by reference - the address of the parameter's storage location


is passed to the subprogram so that operations may be done directly on
the parameter. The subprogram will be able to change the value of the
parameter that is passed by reference (aka the variable parameter).

2. Pointers can be passed as arguments in function calls.


a) A pointer to the variable is passed by value to the function. In other
words, the address of the variable is the actual parameter to the
function.
b) The pointer is dereferenced, allowing the change of the contents
pointed to by the address contained in the pointer. The address itself
cannot be modified by the function, but the contents of the address can
be changed.

7
OOP Course Al-Balqa Applied
Unviversity

POINTERS AS FUNCTION PARAMETERS (CONTINUED)

/* param.cpp
*
* Synopsis - Displays the values of variables and parameters
* before, during, and after a function call.
*
* Objective - Illustrates passing pointer parameters.
*/

// Include Files
#include <iostream.h>

// Function Declarations
void changit( int, int * );

void main( void )


{
int x, y, *int_ptr;

x = 1;
y = 3;
int_ptr = &y; // the value of y will eventually be changed by changit()

cout << "In main before the call to changit,";


cout << " x = " << x << ", y = " << y << ", *int_ptr = " << *int_ptr << endl;

changit( x, int_ptr ); // the function call could also have been


// changit ( x, &y);

cout << "In main after the call to changit,"; // x will be unchanged
cout << " x = " << x << ", y = " // y will be changed
<< y << ", *int_ptr = " << *int_ptr << endl;
}

8
OOP Course Al-Balqa Applied
Unviversity

POINTERS AS FUNCTION PARAMETERS (CONTINUED)

/***************** changit() **********


// Assigns values to x and *int_ptr and displays the
// assigned values.
void changit( int x, int *int_ptr ) // int_ptr contains the address of y
{
x += 5; // the copy of x is changed
*int_ptr += 5; // the contents of y is changed

cout << "In changit, x = " << x // print will differ from
<< ", *int_ptr = " << *int_ptr << endl; // print in main()
}

Output is:

In main before the call to changit, x = 1, y = 3, *int_ptr = 3


In changit, x = 6, *int_ptr = 8
In main after the call to changit, x = 1, y = 8, *int_ptr = 8

9
OOP Course Al-Balqa Applied
Unviversity

FREE STORE OPERATORS "NEW" AND "DELETE"

1. The new and delete operators are used to perform dynamic memory
allocation (for any built-in or user-defined type).

2. To allocate space from the heap to store an integer, you would write:

int *intPtr;
intPtr = new int;

3. The new operator:


a) Automatically creates an object of the proper size.
b) Calls the constructor for the object, if necessary.
c) Returns a pointer of the correct type.
d) If new is unable to find space, it returns a 0 pointer.

4. To free the space for an object created by new in C++, you must use the
delete operator as follows:

delete intPtr;

a) delete eliminates a dynamic variable and returns the memory that the
dynamic variable occupied to the heap. The memory can then be
reused to create new dynamic variables.
b) delete returns type void.
c) delete invokes the class destructor if necessary.

5. C++ allows you to provide an initializer for a newly created object. In the
following, the newly created float object is initialized to 3.14159:

float *thingPtr = new float (3.14159);

10
OOP Course Al-Balqa Applied
Unviversity

TYPEDEFS

1. The keyword typedef provides a mechanism for creating synonyms (or


aliases) for previously defined data types.

2. Names for structure types are often defined with typedef to create shorter or
more readable type names.
a) The following example defines the new type name CardPtr as a
synonym for type Card *:

struct Card {
int face;
int suit;
};

typedef Card* CardPtr;

b) After the typedef, the new identifier can be used to declare variables of
that type.

CardPtr ptr_to_card;

3. Creating a new name with typedef does not create a new data type.
a) typedef simply creates a new type name which may then be used in the
program as an alias for an existing type name.

4. typedef declarations are often put in header files.

5. Synonyms for built-in data types can be created with typedef.

6. Using typedef can help make a program more portable.


a) For example, a program requiring 4-byte integers may use type int on
one system and type long int on another system that has 2-byte
integers.

11
OOP Course Al-Balqa Applied
Unviversity

TYPEDEFS (CONTINUED)

i) Programs designed for portability can use typedef to create an


alias such as Integer for 4-byte integers.
ii) Integer can then be aliased to int on systems with 4-byte integers

typedef int Integer;

and can be aliased to long int on systems with 2-byte integers


where long int values occupy 4 bytes.

typedef long int Integer;

iii) Then, to write portable programs, the programmer simply


declares all 4-byte integer variables to be of type Integer.

12
OOP Course Al-Balqa Applied
Unviversity

STORAGE CLASSES

1. The attributes of a variables include:


a) Name
b) Type
c) Size
d) Value

2. Variables can have other attributes known as storage class specifiers:


a) A variable's storage class specifier helps determine its:
i) Storage class
a) Storage class determines the period during which that
identifier exists in memory.
b) Some identifiers exist briefly, some are repeatedly created
and destroyed, and others exist for the entire execution of
a program.
ii) Scope
a) Scope is where the identifier can be referenced in a
program.
b) Some identifiers can be referenced throughout a program,
while others can be referenced from only limited portions
of a program.
iii) Linkage
a) An identifier's linkage determines for a multiple-source-
file program whether an identifier is known only in the
current source file or in any source file with proper
declarations.
b) Four class specifiers are:
i) auto
ii) register
iii) extern
iv) static

13
OOP Course Al-Balqa Applied
Unviversity

AUTOMATIC AND REGISTER VARIABLES

1. The auto and register keywords are used to declare variables of the
automatic storage class. Such variables are created when the block in which
they are declared is entered, they exist while the block is active, and they are
destroyed when the block is exited.

2. Only variables can be of automatic storage class, i.e. they exist only in the
body of the function in which the declaration appears.
a) Automatic storage is a means of conserving memory because automatic
storage class variables are created when the block in which they are
declared is entered and are destroyed when the block is exited.
b) A function's local variables and parameters normally are of automatic
storage class so the auto keyword is rarely used.
c) The storage class specifier auto explicitly declares variables of
automatic storage class.
i) In the following declaration, float variables x and y are local
variables of automatic storage class.

auto float x, y;

3. The storage class specifier register can be placed before an automatic


variable declaration to suggest that the compiler maintain the variable in one
of the computer's high-speed hardware registers rather than in memory.
a) If intensely used variables such a counters or totals can be maintained
in hardware registers, the overhead of repeatedly loading the variables
from memory into the registers and storing the results back into
memory can be eliminated.
b) The compiler may ignore register declarations (e.g. there may not be a
sufficient number of registers available for the compiler to use).
c) The following declaration suggests that the integer variable counter be
placed in one of the computer's registers:

register int counter = 1;

d) The register keyword can be used only with local variables and
function parameters.

14
OOP Course Al-Balqa Applied
Unviversity

AUTOMATIC AND REGISTER VARIABLES (CONTINUED)

e) A common programming error is to use multiple storage class


specifiers for an identifier.
i) Only one storage class specifier can be applied to an identifier.
For example, if you include register, do not also include auto.
f) Often, register declarations are unnecessary. Today's optimizing
compilers are capable of recognizing frequently used variables and can
decide to place them in registers without the need for a register
declaration from the programmer.

15
OOP Course Al-Balqa Applied
Unviversity

EXTERNAL AND STATIC IDENTIFIERS

1. The keywords extern and static are used to declare identifiers for variables
and functions of the static storage class.
a) Such variables exist from the point at which the program begins
execution.
b) For variables, storage is allocated and initialized once when the
program begins execution.
c) For functions, the name of the function exists when the program begins
execution.
d) Even though the variables and the function names exist from the start
of the program execution, this does not mean that these identifiers can
be used throughout the program.
i) Storage class and scope have a controlling influence.

2. There are two types of identifiers with static storage class:


a) External identifiers such as global variables and function names.
i) Global variable and function names default to storage class
specifier extern.
b) Local variables declared with the storage class specifier static.

3. Global variables:
a) Are created by placing variable declarations outside any function
definition.
b) Retain their values throughout the execution of the program.
c) When defined, they are known from their point of declaration to the
end of the source file.
d) Have external linkage; this means that they can also be referenced in
other source code files as well as in functions below their point of
definition.
i) Code in other source code files can declare (but not define) this
same variable and give it the storage class extern.

16
OOP Course Al-Balqa Applied
Unviversity

EXTERNAL AND STATIC IDENTIFIERS (CONTINUED)

ii) For example, if a source code file, containing the function


main(), defined an external variable, it might have the following
structure:

int globevar; // globalvar is defined and storage allocated


main()
{
...
}

a) If function f1() in another source code file needed to


access the variable globalvar, it could include an extern
declaration at the top of the source file.

extern int globalvar;

f1()
{
...
}

iii) The keyword extern is used with declarations, but not with
definitions of variables.
a) It indicates that the variable is defined elsewhere.
b) References should be resolved during the link phase of
compilation.

4. Global variables and functions can be referenced by any function that follows
their declarations for definitions in the file.

17
OOP Course Al-Balqa Applied
Unviversity

EXTERNAL AND STATIC IDENTIFIERS (CONTINUED)

5. Global vs. local variables:


a) Declaring a variable as global rather than local allows unintended side
effects to occur when a function that does not need access to the
variable accidentally or maliciously modifies it. In general, use of
global variables should be avoided except in certain situations with
unique performance requirements.
b) Variables used only in a particular function should be declared as local
variables in the function rather than as global variables.

6. Local variables declared with the keyword static are known only in the
function in which they are defined, but unlike automatic variables, static local
variables retain their value when the function is exited. The next time the
function is called, the static local variable contains the value it had when the
function last exited.
a) All numeric variables of the static storage class are initialized to zero if
they are not explicitly initialized by the programmer.
b) The following statement declares local variable count to be static and
to be initialized to 1.

static int count = 1;

c) Example of program that uses static local variables is on next page.

18
OOP Course Al-Balqa Applied
Unviversity

EXTERNAL AND STATIC IDENTIFIERS (CONTINUED)

// A scoping example

#include <iostream.h>

void a(void); // function prototype


void b(void); // function prototype
void c(void); // function prototype

int x = 1; // global variable

main()
{
int x = 5; // local variable to main

cout << "local x in outer scope of main is " << x << endl;

{ // start new scope


int x = 7;

cout << "local x in inner scope of main is " << x << endl;
} // end new scope

cout << "local x in outer scope of main is " << x << endl;

a(); // a has automatic local x


b(); // b has static local x
c(); // c uses global x
a(); // a reinitializes automatic local x
b(); // static local x retains its previous value
c(); // global x also retains its value

cout << "local x in main is " << x << endl;

return 0;
}

19
OOP Course Al-Balqa Applied
Unviversity

GLOBAL, AUTOMATIC LOCAL, AND STATIC LOCAL VARIABLES


(CONTINUED)

void a(void)
{
int x = 25; // initialized each time a is called

cout << endl << "local x in a is " << x


<< " after entering a" << endl;
++x;
cout << "local x in a is " << x
<< " before exiting a" << endl;
}

void b(void)
{
static int x = 50; // Static initialization only
// first time b is called.
cout << endl << "local static x is " << x
<< " on entering b" << endl;
++x;
cout << "local static x is " << x
<< " on exiting b" << endl;
}

void c(void)
{
cout << endl << "global x is " << x
<< " on entering c" << endl;
x *= 10;
cout << "global x is " << x << " on exiting c" << endl;
}

20
OOP Course Al-Balqa Applied
Unviversity

GLOBAL, AUTOMATIC LOCAL, AND STATIC LOCAL VARIABLES


(CONTINUED)

Output is:

local x in outer scope of main is 5


local x in inner scope of main is 7
local x in outer scope of main is 5

local x in a is 25 before entering a


local x in a is 26 before exiting a

local static x is 50 on entering b


local static x is 51 on exiting b

global x is 1 on entering c
global x is 10 on exiting c

local x in a is 25 on entering a
local x in a is 26 before exiting a

local static x is 51 on entering b


local static x is 52 on exiting b

global x is 10 on entering c
global x is 100 on exiting c
local x in main is 5

21
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS

1. The following program demonstrates an array class:


a) Performs range checking to ensure that subscripts remain within the
bounds of the array.
b) Allows one array object to be assigned to another with the assignment
operator.
c) Objects of this array class automatically know their size so the size
does not need to be passed separately as an argument when passing an
array to a function.
d) Entire arrays can be input or output with the stream-extraction and
stream-insertion operators, respectively.
e) Array comparisons can be made with the equality operators == and !=.
f) The program uses the overloaded subscript operator to:
i) Reference element integers1[5]--an in-range element of
integers1.
ii) Use integers[5] as an lvalue on the left side of an assignment
statement in which the array element is assigned a new value.
iii) Reference an out-of-range element integers1[15].
g) The array subscript operator [] is not restricted for use only with
arrays; it can be used to select elements from other kinds of container
classes such as linked lists, strings, dictionaries, and so on. Also
subscripts no longer have to be integers; characters or strings could be
used, for example.

22
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// ARRAY1.H
// Simple class Array (for integers)
#ifndef ARRAY1_H
#define ARRAY1_H

#include <iostream.h>

class Array {
friend ostream &operator<<(ostream &, const Array &);
friend istream &operator>>(istream &, Array &);
public:
Array(int = 10); // default constructor
Array(const Array &); // copy constructor
~Array(); // destructor
int getSize() const; // return size
Array &operator=(const Array &); // assign arrays
int operator==(const Array &) const; // compare equal
int operator!=(const Array &) const; // compare !equal
int &operator[](int); // subscript operator
private:
int *ptr; // pointer to first element of array
int size; // size of the array
};

#endif

23
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// ARRAY1.CPP
// Member function definitions for class Array
#include <iostream.h>
#include <stdlib.h>
#include <assert.h>
#include "array1.h"

// Default constructor for class Array


Array::Array(int arraySize)
{
size = arraySize; // default size is 10
ptr = new int[size]; // create space for array
assert(ptr != 0); // terminate if memory not allocated

for (int i = 0; i < size; i++)


ptr[i] = 0; // initialize array
}

// Copy constructor for class Array


Array::Array(const Array &init)
{
size = init.size; // size this object
ptr = new int[size]; // create space for array
assert(ptr != 0); // terminate if memory not allocated

for (int i = 0; i < size; i++)


ptr[i] = init.ptr[i]; // copy init into object
}

24
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// Destructor for class Array


Array::~Array()
{
delete [] ptr; // reclaim space for array
}

// Get the size of the array


int Array::getSize() const { return size; }

// Overloaded assignment operator


Array &Array::operator=(const Array &right)
{
if (&right != this) { // check for self-assignment
delete [] ptr; // reclaim space
size = right.size; // resize this object
ptr = new int[size]; // create space for array copy
assert(ptr != 0); // terminate if memory not allocated

for (int i = 0; i < size; i++)


ptr[i] = right.ptr[i]; // copy array into object
}
return *this; // enables x = y = z;
}

// Determine if two arrays are equal and


// return 1 if true, 0 if false.
int Array::operator==(const Array &right) const
{
if (size != right.size)
return 0; // arrays of different sizes
for (int i = 0; i < size; i++)
if (ptr[i] != right.ptr[i])
return 0; // arrays are not equal
return 1; // arrays are equal
}

25
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// Determine if two arrays are not equal and


// return 1 if true, 0 if false.
int Array::operator!=(const Array &right) const
{
if (size != right.size)
return 1; // arrays of different sizes

for (int i = 0; i < size; i++)


if (ptr[i] != right.ptr[i])
return 1; // arrays are not equal

return 0; // arrays are equal


}

// Overloaded subscript operator


int &Array::operator[](int subscript)
{
// check for subscript out of range error
assert(0 <= subscript && subscript < size);

return ptr[subscript]; // reference return creates lvalue


}

// Overloaded input operator for class Array;


// inputs values for entire array.
istream &operator>>(istream &input, Array &a)
{
for (int i = 0; i < a.size; i++)
input >> a.ptr[i];

return input; // enables cin >> x >> y;


}

26
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// Overloaded output operator for class Array


ostream &operator<<(ostream &output, const Array &a)
{
for (int i = 0; i < a.size; i++) {
output << a.ptr[i] << ' ';

if ((i + 1) % 10 == 0)
output << endl;
}

if (i % 10 != 0)
output << endl;

return output; // enables cout << x << y;


}

27
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// FIG8_4.CPP
// Driver for simple class Array
#include <iostream.h>
#include "array1.h"

main()
{
// create two arrays
Array integers1(7), integers2;

// print integers1 size and contents


cout << "Size of array integers1 is "
<< integers1.getSize() << endl
<< "Array after initialization:" << endl
<< integers1 << endl;

// print integers2 size and contents


cout << "Size of array integers2 is "
<< integers2.getSize() << endl
<< "Array after initialization:" << endl
<< integers2 << endl;

// input and print integers1 and integers2


cout << "Input 17 integers:" << endl;
cin >> integers1 >> integers2;
cout << "After input, the arrays contain:" << endl
<< "integers1: " << integers1
<< "integers2: " << integers2 << endl;

28
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// use overloaded inequality (!=) operator


cout << "Evaluating: integers1 != integers2" << endl;
if (integers1 != integers2)
cout << "They are not equal" << endl;

// create array integers3 using integers1 as an


// initializer; print size and contents
Array integers3(integers1);

cout << endl << "Size of array integers3 is "


<< integers3.getSize() << endl
<< "Array after initialization:" << endl
<< integers3 << endl;

// use overloaded assignment (=) operator


cout << "Assigning integers2 to integers1:" << endl;
integers1 = integers2;
cout << "integers1: " << integers1
<< "integers2: " << integers2 << endl;

// use overloaded equality (==) operator


cout << "Evaluating: integers1 == integers2" << endl;
if (integers1 == integers2)
cout << "They are equal" << endl << endl;

// use overloaded subscript operator to create rvalue


cout << "integers1[5] is " << integers1[5] << endl;

// use overloaded subscript operator to create lvalue


cout << "Assigning 1000 to integers1[5]" << endl;
integers1[5] = 1000;
cout << "integers1: " << integers1 << endl;

29
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

// attempt to use out of range subscript


cout << "Attempt to assign 1000 to integers1[15]" << endl;
integers1[15] = 1000; // ERROR: out of range

return 0;
}

Output is:

Size of array integers1 is 7


Array after initialization:
0000000

Size of array integers2 is 10


Array after initialization:
0000000000

Input 17 integers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
After input, the arrays contain:
integers1: 1 2 3 4 5 6 7
integers2: 8 9 10 11 12 13 14 15 16 17

Evaluating: integers1 != integers2


They are not equal

Size of array integers3 is 7


Array after initialization:
1234567

30
OOP Course Al-Balqa Applied
Unviversity

CASE STUDY: AN ARRAY CLASS (CONTINUED)

Assigning integers2 to integers1:


integers1: 8 9 10 11 12 13 14 15 16 17
integers2: 8 9 10 11 12 13 14 15 16 17

Evaluating: integers1 == integers2


They are equal

integers1[5] is 13
Assigning 1000 to integers1[5]
integers1: 8 9 10 11 12 1000 14 15 16 17

Attempt to assign 1000 to integers[15]


Assertion failed: 0 <= subscript && subscript < size,
file ARRAY1.CPP, line 93
Abnormal program termination

31
OOP Course Al-Balqa Applied
Unviversity

COPY CONSTRUCTOR

1. In the Array case study, the following function prototype is a copy


constructor:

Array(const Array &);

2. A copy constructor is used to initialize an object with another object of the


same class. The above initializes an Array object by making a copy of an
existing Array object.

3. Copying must be done carefully to avoid the pitfall of leaving both objects
pointing to the same dynamically allocated storage, exactly the problem that
would occur with default memberwise copy.
a) If a copy constructor copies a pointer in the source object to the target
object's pointer, then both objects would point to the same dynamically
allocated storage.
b) The first destructor to execute would then delete the dynamically
allocated storage and the other object's pointer would then be
undefined, a situation likely to cause a serious runtime error.

4. Copy constructors are invoked whenever a copy is needed such as:


a) In call-by-value.
b) When returning an object by value via the function type from a called
function.
c) When initializing an object to be a copy of another object of the same
class.

Array integers3(integers1); // copy constructor invoked

5. Copy constructors must receive reference parameters.


a) Otherwise, the copy constructor call results in infinite recursion
because, for call-by-value, a copy of the object passed to the copy
constructor must be made which results in the copy constructor being
called again.

32
OOP Course Al-Balqa Applied
Unviversity

ASSIGNMENT OPERATOR

1. In the Array case study, the following function prototype is an overloaded


assignment operator:

Array & operator=(const Array &);

2. When the compiler sees an expression such as:

integers1 = integers2;

it invokes the operator= function by generating the call:

integers1.operator=(integers2)

3. The operator= member function should test for self assignment.

4. By returning a reference, concatenated Array assignments such as x=y=z are


permitted.

5. When the operator = appears in a statement:


a) The copy constructor is invoked if the left operand has not been
previously instantiated.
b) The overloaded assignment operator = function is invoked if the left
operand has been previously instantiated.

6. If an overloaded assignment operator is not defined, assignment is still


allowed, but it defaults to a memberwise copy of each data member.
a) In some cases this is acceptable.
b) For objects that contain pointers to dynamically allocated storage,
memberwise copy results in two different objects pointing to the same
dynamically allocated storage. When the destructor for either of these
objects is called, the dynamically allocated storage is released. If the
other object then refers to that storage, the result is undefined.

33
OOP Course Al-Balqa Applied
Unviversity

BIBLIOGRAPHY

Barkakati, Nabajyoti, Borland C++ 4 Developer's Guide, Indianapolis, Indiana:


SAMS Publishing, 1994.

Cantu, Marco and Steve Tendon, Borland C++ 4.0 Object-Oriented Programming,
New York: Random House, 1994.

Deitel, H.M. and P.J. Deitel, C++ How to Program, Second Edition, Eaglewood
Cliffs, New Jersey: Prentice Hall, 1998.

Foster, L.S., C by Discovery, Second Edition, El Granada, CA: Scott/Jones Inc.,


Publishers, 1994.

Gorlen, Keith E., Sanford M. Orlow, and Perry S. Plexico, Data Abstraction and
Object-Oriented Programming in C++, New York: John Wiley & Sons, 1991.

Horstmann, Cay S., Mastering Object-Oriented Design in C++, New York, NY:
John Wiley & Sons, Inc., 1995.

Savitch, Walter, Problem Solving with C++, Second Edition, Menlo Park, Ca.:
Addison-Wesley Publishing Company, Inc., 1999.

Swan, Tom, Mastering Borland C++ 4.5, Second Edition, Indianapolis, Indiana:
SAMS, 1995.

34

You might also like