Last updated 24 March 2006, 16:57 PT, AHD

 

CSCI101

An Introduction to Programming using C++

 

Chapter 6

 

Defining Classes and

Abstract Data Types

 

6.1 Structures

6.2 Classes

6.3 Abstract Data Types

 

 

 

 

6.1 Structures

 

Structures are very closely related to classes.

A structure is a class without the member functions.

 

What is a Structure?

 

A structure is a collection of data items

treated as a single entity.

The data items may be of different data types. . .

 

A Structure Definition

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

};

 

 

A Structure Definition

 

struct Student //Student is the structure name

{

   int student_number; //a structure member

   int exam_score; //a structure member

   char grade; //a structure member

};

 

Where do you place the structure definition?

 

You should place the structure definition

before any function prototypes in your program

- before the start of the main function.

That way, your structure is available to all parts of your program.

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

}; // DON'T FORGET THE ;

 

void get_grade(int score);

 

int main()

{

// etc.

}

 

Declaring Structure Variables

 

There are two ways to declare structure variables:

 

You can declare structure variables at the place where the structure is defined. . .

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

} // This declares 2

 

// variables of type Student. Note the ;

 

void get_grade(int score);

 

int main ( )

{

// etc.

}

 

Declaring Structure Variables

 

You can also declare structure variables anywhere in the code

where you normally declare variables. . .

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

};

 

void get_grade(int score);

 

int main( )

{

 

// declare just like standard variables

}

 

 

Using Structure Variables

 

Student student1;

student1.student_number = 1234;

student1.exam_score = 90;

student1.grade = 'A';

 

// the dot operator is used just

// like it is used

// with classes and member

// functions eg cin.get(next);

 

Other Assignments

 

Structure variables can be assigned other structure variables,

making all their member values the same:

 

student1 = student2;

 

Initializing Structure Variables

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

};

 

void get_grade(int score);

 

int main( )

{

   Student student1, student2;

 

 

}

 

 

Initializing Structure Variables

 

Student student1;

student1.student_number = 1234;

student1.exam_score = 90;

student1.grade = 'A';

 

The four statements shown above can be written as a single statement:

 

Student student1 = {1234,90,'A'};

 

An Illegal Structure Initialization

 

Student student1 = {1234,90,'A','B'};

 

The Student structure

 

has only three members. If you try to

initialize a structure variable

with more values than it has members,

you will get a compiler error.

 

 

 

 

Initializing Structure Variables

 

You can initialize a structure variable with fewer values than it has members.

 For example, the following statement:

 

Student student1 = {1234};

 

means that the first member variable is assigned the integer 1234,

and the other two variables are set to default values

for their data type (0 and a null character).

 

 

Structure members can be structures

 

A structure member can itself be a structure,

but cannot be the same structure as its parent structure.

 

For example the following is not allowed. . .

 

A structure cannot contain the same structure as a member

 

struct Student

{

   int student_number;

   int exam_score;

   char grade;

   Student any_student; // NOT ALLOWED

};

 

 

Structures as Function Arguments

 

Structures can be call-by-value

or call-by-reference arguments to functions.

 

A structure can also be the return type of a function:

 

Student get_student_info(void);

 

A Structure Definition:

 

06-01.cpp

 

 

 

 

6.2 Classes

 

Classes

A class is a data type whose variables are objects

 

Objects can contain data and functions

 

 

Encapsulation

Combining a number of items, such as variables and functions,

into a single package, such as an object of some class, is called encapsulation.

 

To obtain a class from a structure

To obtain a class from a structure just add functions. . .

 

A Class with a Member Function:

 

06-03.cpp

 

 

Private

 

The keyword private means that the class's data and functions

can only be accessed by a member function of the same class.

 

 

Public

 

The keyword public means that the data and member functions

of a class can be accessed from anywhere in a program,

i.e. from the main function or from any other function,

not just member functions.

 

Class definitions contain only the member function prototype

 

06-03.cpp

 

class DayOfYear

{

public:

void output( ); // the prototype

int month;

int day;

};

 

 

Class definitions

 

Class definitions are placed before the main() function, just like structure definitions.

 

Declaring class variables (objects)

 

 

DayOfYear today, birthday;

 

 

Calling a member function

 

today.output();

birthday.output();

 

Where do you place the member function definitions?

 

Member function definitions are placed after the main() function

in a program, just like other user-defined functions.

(They could be placed in a separate file from the main() function).

 

 

Member functions definitions

 

When member functions are defined must start with

the class name of the class to which they belong:

 

void DayOfYear::output()

{

// statements

}

 

 

Member function overload

 

Two different classes may contain a member function of the same name.

The scope resolution operator is always used with the class name on its left,

and the member function name on the right.

 

The correct use of public and private

 

In order to create a class which is known as an Abstract Data Type,

you must declare all the data member variables as private ,

and (usually) all member functions as public.

 

If you design your program so that only member functions

can have access to the member variables

(by using private member variables),

you are hiding the data from other parts of the program,

and thus protecting the data against unintentional changes.

 

Allowing only member functions

to have access to member variables

makes the program more understandable and robust.

 

It means that if you need to make any changes

to your member variables,

you need only change the member function definitions

to match the changes,

and no other part of the program needs to be changed.

 

 

 

Member variables marked as private can only

be accessed by a member function belonging

to the same class as the member variable.

 

 

A program may also contain private member functions. . .

 

 

private member functions

 

A private member function can only be accessed

by a member function belonging to the same class as the member function.

 

06-04.cpp

 

This program uses private member variables and public member functions.

It is a vast improvement on program 06-03.cpp, as only the member functions

now have access to the member variables.

 

 

 

Object Assignments

 

Object variables can be assigned another object variable,

making all their member values the same:

 

Student student1,student2;

student1 = student2;

// just like structures!

 

 

 

Constructors for Initialization

 

A constructor is a member function that is automatically called

when a member of its class is declared.

 

Constructors provide initial values

 

Constructors are generally used to provide initial (starting) values to member variables.

 

 

 

 

Defining a constructor

 

You define a constructor the same way that you define

any other member function,

but a constructor must have the same name as its class

and cannot return a value,

in fact cannot have a return type - not even void.

 

 

 

Calling Constructor functions

 

Constructor functions are called when an object is declared,

hence constructor member function prototypes must be placed

in the public section of the class definition,

otherwise they could not be used in other parts of the program to declare variables.

 

Important

 

Constructor member functions cannot be called

in the way that other member functions are called.

 

Constructors are called automatically when a variable of the same class is declared.

 

06-06.cpp

 

 

Abstraction

 

abstraction is the result of

converting a complex thing

into a simple thing. . .

 

 

Abstraction Example

 

Question: What has four walls, a door, windows and a roof?

 

Answer: a house

 

Abstraction

 

*    means listing the essentials and hiding the details

 

*    the opposite of abstract means to show all the details of an object

 

 

Abstraction
IS
Information Hiding

 

 

Information Hiding
IS
Abstraction

 

Information Hiding
IS
Encapsulation

 

 

 

 

Why is abstraction used in C++ programs?

 

Abstraction is used in a programming language

to make it easier for the programmer to focus on

the essential parts of a program, and not get bogged down by the details.

 

Hiding information simplifies programs

by grouping together data relevant to an object

and hiding the data from other objects (or programmers). . .

 

A programmer can use the member functions of a class

which was written by another programmer without even seeing the source code.

 

 

All a programmer needs to know

is what data is required as input to the function,

and what data (if any) is returned.

 

 

The Black Box Analogy

 


 

 

 

 

 

 

 


Abstraction in Programming

 

To use a member function of a class,

all a programmer needs to know

is what data is required as input to the method,

and what data (if any) is returned.

 

The information about the input and output data of a member function

are known as the function's preconditions and postconditions, respectively.

 

 

Documentation of Regular Functions

 

Preconditions and postconditions of regular functions

are usually documented either as comments

just above the function definition in the source code,

or just above its declaration (prototype). . .

 

// Precondition:

// num1 and num2 have a non-zero value

// Postcondition:

// The larger of the two numbers is returned

int getLarger(int num1, int num2)

{

 

if (num1 > num2)

return num1

else

return num2

}

 

 

Documentation of Member Functions

 

Preconditions and postconditions of a class's member functions

are usually documented as comments just above

the function declaration (prototype) within the class definition.

 

// Precondition:

// new_month and new_day form a possible date.

// Postcondition:

// The date is reset according to the arguments.

void set(int new_month, int new_day);

 

 

In C++ you can separate your class declaration and its implementation into two files.

If you give the compiled version of the class declaration file to another programmer,

with external documentation in the form of pre- and post-condition comments,

the programmer can use the member functions of the class without having to

study the source code. Indeed, they do not need the .cpp source code at all to use the class.

 

You do not need the source code to be able to use a class

 

This is like saying that you don't need to know

the details of how a calculator works

to be able to use it.

It is what you put in and what comes out that matters.

How the calculator does it is irrelevant.

 

Buying classes from a software vendor

 

You can buy classes from software vendors to use with your own programs,

saving you the job of writing them yourself.

The vendor gives you the binary code version of the class file,

and documentation on how to use it.

 

Unless the code is 'Open Source', you will not be able to inspect the source code.

 

 

Abstract Data Types

 

An abstract data type (ADT) is a data type (a class)

which exhibits information hiding and encapsulation.

 

Classes and ADT

 

Classes should be designed to be abstract data types. . .

 

Implementing an ADT Class

 

1. Summarize the purpose of the class in comments at the top of the file in which the class is defined.

2. make instance variables private

3. provide public accessor and mutator functions.

4. write pre- and post-condition comments for every function

5. make helping functions private

 

A class which is an ADT

has two parts:

 

interface

and

implementation

 

The ADT Interface

The interface is simply the set of public function headers and associated comments.

 

These define the 'behaviour' of the class.

Put another way, the interface specifies how to interact with objects of this class.

 

 

interface

and

implementation

 

 

The implementation is simply the code which

defines the function.

 

 

Encapsulation

 

Encapsulation means that the data and functions relevant to an object,

are stored together as a single entity, and the details are hidden.

 

 

Section 6.3 Abstract Data Types

 

Section 6.3 of the textbook is a read-only section.

 

Homework

 

Read Chapter 6, paying close attention to Section 6.3 on Abstract Data Types