Title: Embedded Systems Programming
1Embedded Systems Programming
2Contents
- Introduction
- User defined data types
- Classes and encapsulation
- Implementation/interface
- Classes and objects
- Creating/initializing objects constructors
- Destroying objects destructors
- Other features of classes
3Introduction
- Classes are the core of Cs support for object
oriented programming - They allow the programmer to create abstract data
types in a similar way that struct does in C - However the C class also supports encapsulation
whereas struct does not - Encapsulation allows the programmer to hide
details about the implementation - First we will review the struct construct
4User defined data types
- C (and C) allow user defined data types to be
created using the struct construct - For example, we could create a Date data type to
represent dates
struct Date int d int m int y
5- We could create variables (objects) of the Date
data type as well as writing functions that
operate on these objects
extern void set_date(Date, int, int,
int) extern void print_date(const
Date) void main() Date date new
Date set_date(date,28,8,2003) print_date(date)
6- In C, we can include the functions as part of
the struct declaration so they become member
functions - This means we dont have to pass the objects as
arguments into the functions
struct Date int d int m int y void
set(int,int,int) void print()
7- The member functions are defined using the
operator as follows
void Dateset(int dd, int mm, int yy) ddd
mmm yyy void Dateprint() printf(D
ay, month, year d d d , d, m, y)
8- Finally Date objects can be created and member
functions called as follows - Note that member functions are called through the
object (variable) name
void main() Date today today.set(12,8,2003)
today.print()
9Classes and encapsulation
- Classes in C are similar and have similar
syntax and uses as structures in C with one key
difference - They support the idea of encapsulation
- The implementation of the class is hidden from
the interface to the class - This is achieved through the use of public and
private member access specifiers
10- We can define a Date class as follows
class Date private int d int m int
y public void set(int,int,int) void
print() void advance()
11- An additional member function advance() has been
added which advances the date by one day - Apart from that, this has the same functionality
as the Date structure - The key difference is the separation of the class
into private and public - This separation underpins the ideas behind
encapsulation (or implementation/interface)
12Key point
- Only public member functions of Date can access
private members of the class - Enforced by rules of the language
- If we try to access a private class member from
outside a public member function, a compilation
error is triggered
13- Implementation of Dateset() is as follows
- Accesses Dated, Datem, Datey which is OK as
its a public member function
void Dateset(int dd, int mm, int yy) ddd
mmm yyy
14- The following is illegal code
- This is an attempt to access a private class
member from outside a public member function
int get_year(Date date) return date.y //
Error! int main() Date today today.d28
// Error! today.m8 // Error! today.y1998
// Error!
15- In order to access the private class members
Dated, Datem, Datey, we have to provide
public member access functions
class Date private int d int m int
y public void set(int,int,int) void
print() void advance() int day() return
d // access function int month() return m
// access function int year() return y //
access function
16- You may wonder (quite rightly!) whether this is
an undue computational overhead - In order to access a private class member, we
have to go through an additional function call - However, access restriction of the classes
private members is key to encapsulation - Implementation/interface
17Implementation/interface
- We can justify the sub-division of a class into
private and public by considering the idea of the
implementation of the class and the interface to
the class - The implementation of the class is represented by
the private class members and public member
function bodies (which use the private members) - The interface to the class is represented by the
public member functions headers
18Date
private
int d int m int y
Implementation
public
void set() void print() void advance() int
date() int month() int year()
Interface
19Changing the implementation of Date
- Suppose we decide to change the implementation of
Date and represent the date internally in the
Julien format - This represents the number of days since 1/1/1900
from which the current day, month and year can be
computed algorithmically
20class Date private long julien // Number
of days since 1/1/1900 public void
set(int,int,int) void print() void
advance() int day() return d // access
function int month() return m // access
function int year() return y // access
function
21- The key point is that public member function body
implementations need to change to reflect the
changed private members - However, the public member function headers
remain the same - These represent the interface to the Date class
as seen by application programs using the class
22Date day() // complicated algorithm Date
month() // complicated algorithm Date
year() // Simple algorithm (taking into
account leap years) Dateadvance() julien
23Key point
- Because of encapsulation, applications using the
Date class will not change as they only interact
with the class through public member function
calls - This leads to more robust extendible systems
24- For example, some external function weekend()
will still be correct even after the changes to
Date - The function interacts with Date through the
public member function day()
int weekend(Date date) // Returns true if the
date falls on a weekend return
((date.day()0)(date.day()6))
25Classes and objects
- Its important to be clear about the distinction
between classes and objects - It may seem obvious but it does cause confusion
- Essentially an object is an instantiation of a
class - We can create many objects of the same class
26- We can create several date objects as follows
Date date date.set(14,4,2003) Date
another_date another_date.set(15,4,2003)
Date
date
Apr 14, 2003
Date
another_date
Apr 15, 2003
27- We have 1 class
- Date
- We have 2 objects
- date
- another_date
- Typically class names will start with upper case
and object names will start with lower case
28Creating/initializing objects constructors
- Objects can be created and initialized by
declaring special public member functions called
constructors with the same name as the class - A nice feature of constructors is that function
overloading can be used so that objects can be
initialized in different ways
29class Date private int d,m,y public D
ate() // constructor Date(int,int,int) //
constructor Date(char ) //
constructor void set(int,int,int) void
print() void advance() int day() return
d // access function int month() return m
// access function int year() return y //
access function
30- The implementation of the constructors are as
follows
DateDate() // default construcotr DateDat
e(int dd, int mm, int yy) ddd mmm
yyy DateDate(char date_string) //
Parse the string and assign to d, m, y
31- We can now create and initialize objects as
follows
Date tomorrow // Date() called Date
today(1,9,1998) // Date(int,int,int)
called Date yesterday("31st August 1998") //
Date(char) called
32- Note that the constructor is automatically called
when an object is declared - It doesnt have to be initialized (although it is
usually good practice to do so) - However, the default constructor must be present
if we wish to create uninitialized objects - Note also that we can create objects dynamically
and this also involves calling a constructor
Date today new Date(1,9,1998) today-gtadvance
()
33Destroying objects destructors
- Destructors are member functions which are called
automatically (see later) in order to delete an
object and release all of the memory taken by
that object - Unlike Java, C has no automatic garbage
collection - For a simple class like Date, no dynamic
allocation of private member variables has taken
place so the compiler can delete Date objects by
simply deleting each private member variable
34- For classes where private members have been
dynamically allocated, we must implement the
destructor in order for the object to be
completely deleted
class myClass private char message int
message_length public myClass(char m, int
len) // constructor myClass() //
destructor
35myClassmyClass(char m, int len) message_leng
thlen messagenew charlen strcpy(message,m)
myClassmyClass() delete message
36- Destructors are called automatically when
- The delete operator is called for a dynamically
created object - An automatically created object goes out of scope
- The program (main) (or a function) terminates for
a statically created object - The destructors for globally defined objects are
called last of all
37Other features of classes
- We will look at a few other features of classes
- this self-reference
- Friends
- Static class members
38Self-reference - this
- Each (non-static) member function has a access to
a pointer to the instantiated object from which
the member function was called (!!) - So, for example, in our Date class, member
functions have access to a (constant) pointer of
type Date
39Date
private
int d int m int y
public
. . void advance() // access to this .
40- The following re-implementation of advance()
makes a copy of a Date object using a
de-referenced this but moved on 1 day
Date Dateadvance() Date dthis // make a
copy d.julien return d Date
d(1,9,1998) Date new_dd.advance()
41- Thus, a completely new initialized Date object is
produced
Date new_d 2/9/98
Date d 1/9/98
42Friends
- A function or a class can be made a friend of
another class - This means that the function or class members can
access the private members of the class - Using the friend keyword in a class declaration
allows encapsulation to be broken and should be
used carefully
43class X . friend int func() friend class
Y .
- This declaration allows func() and all of Ys
member functions to access the private parts of
class X - Note that it is the designer of class X who
specifies the friend relationships
44 class Date private int d,m,y public
Date(int,int,int) // constr. . friend
int weekend(Date) int weekend(Date
date) return ((date.d0)(date.d6)) //
OK!
45Static class members
- Each object has its own copy of all non-static
date members of a class - A static class members belongs to the class
- There is only 1 class wide copy
- Useful for maintaining class wide information
- static class data members exist even if an object
hasnt been instantiated
46- static class members still have private, public
privileges - Only static public member functions can access
static private members if an object has yet to be
instantiated - In this case the member function is accessed
through the class name using the operator - Once an object has been instantiated, static
members can be accessed through non-static public
member functions also - static class members must be initialized once and
once only before use
47- A static class member num_objects can be used to
keep a track on the number of objects of a
certain class that have been created
class myClass private static int
num_objects public myClass()
num_objects static int get() return
num_objects
48int myClassnum_objects0 // Initialize
static void main() printf(num objects so far
d , myClassget()) // prints 0 myClass
m1 myClass m2 myClass m3new myClass()
printf(num objects so far d ,
myClassget()) // prints 3
49And finally ..
- The key message in this lecture is encapsulation
and implementation/interface separation - This leads to self-contained software units
classes which are the basis of object oriented
programming - Object oriented applications comprise a set of
objects, interacting through their class
interfaces - The next lecture looks at inheritance and
polymorphism which allow for flexible object
behaviour, a key element of OOP