You are on page 1of 8

Classes and Data Abstraction

OOP encapsulates data(attributes) and functions(behaviors) into packages called


classes.

A class is a user-defined data type that acts as a blueprint for instantiating any number
of objects of that class.

Classes have property of information hiding i.e. a class know how to communicate with
another class across well-defined interface, however, they are not allowed to know how
they are implemented i.e. implementation is hidden.

C & other procedural languages are action-oriented. In C, unit of programming is


function. Verbs in system specifications help in determining required set of functions.

C++ is object-oriented language. Unit of programming is classes from which objects are
eventually instantiated. Nouns in system specifications help in identifying required
classes.

C++ classes are natural evolution of C struct which is a collection of related variables
whereas a class contains both variables (data members) and functions (member
functions) that manipulate those data.

Member functions are also called operations or methods. Methods are invoked in
response to messages sent to an object. A message corresponds to a member function
call sent from one object to another or sent from a function to an object.

General syntax of a class is

Class className
{
access-specifier 1: ---------------- can be public, private or protected
className( ); //constructor
member function prototypes;
access-specifier 2:
data member declarations;

};--------------Forgetting this is a syntax error

Member Access Specifiers


Public Accessible where the program has access to an object of that
class
Private Accessible only to member functions and to friends of that class
A member access specifier can be used anywhere and any number of times but it is
better to keep all declarations at the top and use a member access specifier only once
Data members are usually private and member functions are public. However, this is not
a hard and fast rule.
Public member functions are also called interface of the class.
Constructor
A member function with the same name as the class.
It initializes the data members of a class object.
Called automatically when an object of that class is created.
There can be many constructors accomplished through function overloading.
Specifying a return type or a return value for a constructor is a syntax error.

Default Constructor is a constructor with no parameters


The default constructor takes no parameters, whether you declare it or get it free from
the compiler
If you declare any constructor, the compiler will not provide a default constructor

Once the class has been defined, it can be used as a type in object, array, pointer or a
reference.
Time sunset, arrayoftimes[5], *ptrToTime,&dTime=sunset ------- C++ is extensible

Data members may be private as they may be of no concern to class’ clients. Thus,
implementation is hidden and this information hiding promotes program modifiability and
simplifies the clients’ perception of a class.

Member functions are usually shorter than non-object oriented programs because the
data stored in data members have ideally been validated by a constructor and/or by
member functions that store new data. Because the data are already in the object, the
member function calls often have no arguments or atleast few arguments than typical
function calls in non object oriented languages. Thus, the calls are shorter, function
definitions are shorter and function prototypes are shorter.

Attempting to initialize a data member of a class explicitly in a class definition is a syntax


error.

Destructor
A member function the same name as the class and with prefix ~ i.e. ~className( );
If no destructor is specified then the system ‘plugs-in’ one destructor.
The destructor does ‘termination housekeeping’ on each class object before the memory
for the object is reclaimed by the system.
Destructors cannot take arguments and hence, cannot be overloaded.
Destructors have no return value.

Declaring member functions inside a class definition (via their function prototypes) &
defining those member functions outside the class definition separates the interface from
of a class from its implementation. This promotes good Software Engineering as it hides
implementation from class’ clients and also class’ need not recompile if implementation
changes; provided interface remains same. Member functions declared outside in a
class definition can be defined outside class definition using binary scope resolution
operator ::. If member function is defined outside then use of class name and :: is
mandatory as it ties function to a class and two classes may have functions with same
name. However, scope of such functions is that of class only.
Member functions defined in class definition are automatically inlined whereas those
defined outside can be inlined using inline keyword. However, compiler reserves the
right whether to inline a function or not.

From performance point of view, smaller functions can be defined in class definition for
making inline but it is not good from Software Engineering point of view because it
exposes code to class’ clients and also clients need to recompile if inline function
changes.

Only simplest and most stable member functions should be defined in class header.
Member function calls generally take either no arguments or substantially fewer
arguments than conventional function calls. This reduces likelihood of passing wrong
arguments. Number of arguments are reduced because of encapsulation of data
members and member functions within an object gives the member functions within an
object gives member functions the right to access the data members.

Member functions are usually designed to be client-oriented rather than implementation


oriented. OOPs imply re-use i.e. crafting valuable classes & creating valuable “software
assests”. Often classes need not be created from scratch. They may be derived from
other classes that provide attributes and behaviors the new classes can use
(inheritance) OR classes can include objects of other classes as members (aggregation
or composition). Such software re-use can greatly enhance programmer’s productivity.

Class Scope and Accessing Class Members


Logically, it may seem that objects may be quite larger because they contain data and
functions. Physically, this is not true. Applying sizeof to a class name or to an object of
that class will report size of class’ data only. This is because the compiler creates
different copies of class’ data for each object because data can vary among objects.
However, the compiler creates only one copy of member functions to be shared by all
objects of that class. It can be shared because function code is non-modifiable (also
called re-entrant code or pure procedure). Data is placed in memory when objects are
defined.

A class’ data members and member functions belong to that class’ scope

Non member functions have file scope

Within a class scope, class members are immediately accessible by all of that class’
member functions and can be referenced by name. Outside class scope, class members
are referenced through one of the handles on an object – an object name, a reference or
a pointer to an object.

An implicit handle is inserted by t he compiler on every reference to a data member or


member function in an object.

Member functions of a class can ONLY be overloaded by other member functions of the
class. Include prototype for each overloaded function in class definition and provide a
separate function definition for each version.

Variables defined in member functions have function scope.


If class data also contains variable with same name then this local variable will hide
class scope variable. To access class scope variable, use :: operator. Hidden global
variables can be accessed using unary scope resolution operator.

To access members of a class, use dot operator with object name or reference and
arrow operator with pointer to object.

Separating Interface from Implementation

Keep class declaration in a header file to be included by any client who want to use the
class

Implementation is kept in a separate source file

Clients don’t need source code; they need only object code of class implementation.
This way no proprietary information is revealed by provided class libraries.

However
Inline functions are revealed
Private members are not accessible but visible, thereby provide hint about
implementation

Information that is internally used by class and not required by class’ clients should be
kept in separate unpublished files. ---Principle of Least Privilege

Use #ifndef, #define and #endif preprocessor directives to prevent header files from
being included more than once in a program like
#ifndef TIME1_H // header file being time1.h
#define TIME1_H
………..
………..
#endif

Controlling Access to Members

Use access specifiers public, private and protected to enforce information hiding & the
principle of least privilege

Don’t use an access specifier multiple times

Keep public members first which acts as public interface

Private members can only be accessed by member functions or friend classes. All other
accesses results in syntax error.

Client of a class can be any member function of other class or a global function.
In struct, all members are public by default whereas in class, they are public. Using
explicit access specifier is a good practice.

‘Access functions (set/get)’ are used to read or modify the value of private data
members.
Advanatges of set functions
Provide data validation capabilities such as range checking to ensure that the value is
set properly.
Translate between the form of data used in the interface and form used in
implementation.

Advantages of get functions (also called query functions)


Need not expose the data in ‘raw’ format

Can edit the data and limit the view of the data the client will see

Get/set functions are not required for every private member

Making data member private and providing public member access functions facilitates
debugging because problems with data manipulation are localized to either the class’
member functions or the friends of the class.

Set/Get make the data public. It is good from software engineering point of view as get
and set put required constraints

Such functions should also provide feedback to client for any wrong setting etc.
//elaborate

Access Functions and Utility Functions

Not all member functions need to be public to serve as part of a class interface. Some of
these can be private to serve as utility functions to other functions of the class.

Predicate functions test the truth or falsity of conditions e.g. isEmpty() or isTrue() for
container class – class capable of holding many objects such as linked list, stack or
queue

Utility functions also called helper functions support the operation of the class’ public
member functions. They are not intended to be used by clients of a class.

Once a class is defined, creating and manipulating objects of that class usually involves
issuing only a simple sequence of member functions calls-few, if any, control structures
are needed. By contrast, it is common to have control structures in the implementation of
a class’ member functions.

Initializing class objects: Constructors


It is good to initialize all data members of a class before using member function.
Such initialization can be done in default constructor, overloaded constructors or through
set functions after object is created. It cannot be done in class definition.

Using default arguments with constructors

A programmer-supplied constructor that default all its arguments (or explicitly requires no
arguments) is also a default constructor i.e. a constructor that can be invoked with no
arguments.
There can be only one default constructor per class

Syntax for default arguments in constructor can be:


className(var1=init_val1,…,varn=init_valn);

If there is an access function doing same initialization as done by constructor, then it is


better to call that access function from constructor passing arguments to it. Using data
members before initializing them properly can cause logic errors. This way ‘Avoid
Repeating Code’ is followed, maintenance becomes easy by reducing likelihood of
programming error when altering the implementation.

Performance of a constructor is enhanced by explicitly declaring the constructor inline or


by defining the constructor in class definition.

Declare default function arguments only in function prototype within the class definition
in header file

Specifying default initializers for the same member function in both header file and
member function definition is a syntax error.

Any change to default arguments of a method requires the client code to be re-compiled.
It islikely that he default argument values will change, use overloaded functions instead.
Thus, if the implementation of a member function changes, the client code need not be
recompiled.

If no constructor is defined the compiler creates a default constructor; however it does


not creates perform any initialization, so when the object is created, it is not guaranteed
to be in a consistent state.

It is possible for a class not to have a default constructor if any constructors are defined
and none of them is explicitly a default constructor

Using Destructors

Declaration: ~className( ); --- No arguments, return types and return values

A class may have only one destructor – destructor overloading is not allowed
~ is a bitwise compliment operator => Destructor is compliment of constructor

Destructor is called automatically when an object is destroyed. E.g. for automatic objects
when program execution leaves the scope in which an object of that class was
instantiated. The destructor does not actually destroy the object – it performs termination
house-keeping before the system reclaims the memory so that memory may be re-used
to hold new objects.

Destructors are appropriate for classes whose objects contain dynamically allocated
memory (for arrays & strings for e.g.) for de-allocation of storage.

When Constructors and Destructors are called


Called automatically.

The order in which these function calls are made depends on the order in which
execution enters & leaves the scope in which objects are instantiated.

Generally, destructors are called in reverse order of the constructor calls

However, the storage class of objects can alter the order in which the destructors are
called.

Constructors are called for objects defined in global scope before any other function
(including main) in that file begins execution (although the order of execution of global
object constructors between files is not guaranteed.

Corresponding destructors are called when main terminates or the exit function is called.

Destructors are not called for global objects if the program is terminated with a call to
function abort.

Constructors are called for automatic local objects when execution reaches the point
where the objects are defined.

Corresponding destructors are called when the objects leave scope i.i. block in which
they are defined exists.

Destructors are not called for automatic objects if the program is terminated with a call to
functions exit or abort.

Constructors are called for static local objects only once when execution first reaches
the point where the objects are defined.

Corresponding destructors are called when main terminates or the exit function is called.

Destructors are not called for static objects if the program is terminated with a call to
function abort.

Using Data Members and Member Functions

Advantages of accessing private data through Get/Set


Protects the data members from receiving invalid values
Also insulates clients of the class from the representation of the data members. Thus, if
the representation of the data changes for some reason (typically to reduce the amount
of storage required or to improve performance), only the member functions need to
change as long as the interface provided by the member functions remains the same.
The clients may, however, need to be recompiled.

A subtle Trap: Returning a Reference to a Private Data Member

Never have a public member function return a non-const reference (or a pointer) to a
private data member. Returning such a reference violates the encapsulation of the class.
In fact, returning any reference or points to private data still makes the client code
dependent on the representation of the class’ data. So, returning pointers or references
to private data should be avoided.

Assignment by Default Memberwise Copy

‘=’ can be used to assign an object to another object of the same type.

It is by default performed by memberwise copy-each member of one object is copied


(assigned) individually to the same member in another object.

Memberwise copy can cause serious problems when used with a class whose data
members contain dynamically allocated storage. However, operator overloading can be
used in this case.

Objects, by default, are passed by call-by-value. (Compare with call-by-reference,


security, performance, use of const)

Objects can be used function arguments

Software Re-usability

Software is increasingly being constructed from existing, well-defined, carefully tested,


well-documented, portable, widely available components (class libraries). Software re-
usability speeds the development of powerful, high quality software. RAD makes use of
components.

Source: How To C++ By Deitel & Deitel

More C++ notes available at:


http://cplusplus-naturally.blogspot.com/