topical media & game development
object-oriented programming
The language C++
C++ is often disparaged because of
its C heritage.
Nevertheless, not only is C++ in many
respects better than C, it also offers much more.
From its conception, C++ has reflected a strong concern
with static typing.
As such it has influenced the ANSI C standard
accepted in 1985.
[ES90] describe most of what has become the ANSI/ISO C++
standard, which is implemented by, among others,
the GNU and Cygnus C++ compilers, and Microsoft Visual C++.
C++ -- is much more than a better C
C
1972 C Kernigan and Ritchi (Unix)
1983 C++ (Simula 1967)
1985 ANSI/ISO C
1996 ANSI/ISO C++
Design principles -- the benefits of efficiency
- superset of C -- supporting OOP
- static typing -- with user-defined exceptions
- explicit -- no default virtual functions
- extensible -- libraries in C and C++
slide: The language C++
The leading design principle underlying C++
is to support object-oriented programming,
yet allow the programmer and user the benefits
of (runtime) efficiency.
It has been designed as (almost)
a superset of C, to allow the integration
of C code in a seamless way.
It provides strong static typing, yet allows
the programmer to escape the rigidity of typing
if absolutely necessary.
C++ is designed to be extensible.
This means that
no assumptions are made with regard to a programming
environment or standard library classes.
The C language was originally introduced
as a (Unix) systems programming language,
and is gradually being replaced by C++ for this purpose.
However, C++ lends itself to many other applications,
including mathematical programming and business applications.
Terminology
The C++ language is without doubt a large and complex language.
Fortunately, an increasing number of textbooks have
become available which provide an appropriate introduction
to C++ and its use for the realization of abstract
data types, including [Heading] and [Weiss93].
Among the additional keywords introduced in C++
(extending C) we have the
keyword const
(which may be used to define constants),
the keyword inline
(which may be used to define inline expanded functions,
that for C have to be defined using macros),
the keyword new
(to dynamically create objects on the heap),
the keyword delete
(to destroy dynamically created objects)
and, finally,
the keywords private, public and
protected
(to indicate access restrictions for the instances
of an object class).
See slide [cc-term].
Keywords:
C++ overview
- inline, new, delete, private, protected, public
Language features:
- constructors -- to create and initialize
- destructors -- to reclaim resources
- virtual functions -- dynamic binding
- (multiple) inheritance -- for refinement
- type conversions -- to express relations between types
- private, protected, public -- for access protection
- friends -- to allow for efficient access
slide: C++ -- terminology (1)
The language features offered by C++
supporting object-oriented programming
include
constructors
(which are defined for each class to create
and initialize instances),
destructors
(which may be used to reclaim resources),
virtual functions
(which must be used to effect dynamic binding),
multiple inheritance
(to specify behavioral refinement),
type conversions
(which allow the user to define coercion relations
between, both system-defined and user-defined,
data types),
and friend declarations
(which may be used to grant efficient access
to selected functions or classes).
The annotated reference manual (ARM) is not a book
to be used
to learn the language, but provides an excellent
source of detailed technical explanations
and the motivations underlying particular
design decisions.
Some basic terminology
name
-- denotes an object, a function, set of functions, enumerator, type,
class member, template, a value or a label
- introduced by a declaration,
- used within a scope, and
- has a type which determines its use.
object
-- region of storage
- a named object has a storage class that determines its lifetime, and
- the meaning of the values found in an object
is determined by the type of the expression
used to access it
slide: C++ -- terminology (2)
To get an idea of the full set of features offered
by C++, look at the meaning of a name in C++ (as described
in the ARM).
See slide [cc-term-2].
A name can either denote an object,
a function, a set of functions, an enumerator, a type
(including classes, structs and unions),
a class member, a template (class or function),
a value or a label.
A name is typically introduced by a declaration,
and is used within a scope.
Moreover, each name has a type which determines its use.
An object in C++ is nothing but a
region of storage,
with a lifetime determined by its storage class
(that is, whether it is created on the stack or on the
heap).
Meaning is given to an object by the type
used to access it, which is determined during compile
time.
The only information needed at runtime in C++
is concerned with virtual functions
(which require a virtual function dispatch table
for dynamic binding).
Expressions
Again due to its C heritage,
C++ supports many basic types
(including int, char and float)
and compound types
(including arrays, functions, pointer types,
reference types, and user-defined class, union or
struct types).
See slide [cc-expr-1].
Type expressions
- basic types -- int, char, float, ...
- array -- int ar[SIZE]
- function -- void f(int)
- pointer -- int* , char*, void (*f)(int)
- reference -- int&, char*&
- class, union, struct -- user-defined
slide: C++ -- expressions (1)
Pointer types encompass pointers to basic types
and pointers to user-defined types,
such as functions and classes.
The difference between object,
reference and
pointer types
may be succinctly characterized as the difference
between the actual thing, an alias
(that looks like the actual thing but isn't)
and an address of the actual thing
(where you have to go to get it).
Expressions
- operators -- + , - ,.., < , <= ,.., == , != ,.., && , ||
- indexing -- o[ e ]
- application -- o(...)
- access -- o.m(...)
- dereference -- p->m(...)
- in/decrement -- o++, o--
- conditional -- b?e1:e2
Assignment
- var = expression
- modifying -- +=. -=, ...
slide: C++ -- expressions (2)
Value expressions may be created using
arithmetic and comparison operators
(including == for equality and !=
for inequality).
As logical operators, C++ includes
conjunction (&&)
and disjunction (),
as well as a number of bitwise logical operators.
Also, we have an indexing operator
(which may be defined for arbitrary types),
an application operator
(which may also be defined for arbitrary types),
an access operator
(which is as a standard used for member function
invocation or method calls),
a dereference operator
(which is used to invoke member functions through a
pointer to an object)
and in- and decrement
operations
(that, again, may be defined for arbitrary types).
Needless to say, user-defined operators
must be applied with care.
Also, we have a conditional expression of the form
b?: testing the condition b to
deliver when it evaluates to true and otherwise.
Also, C++ allows for sequencing within expressions
of the form ,
which evaluates in that order
and delivers as its value.
Assignments in C++, it is important to note,
are written as var = expression with a single =
symbol.
This convention is known to cause mistakes by programmers
raised with languages such as Pascal or Modula-2.
In addition, C++ offers modifying assignments,
which may be used as, for example, in n += 1,
which is identical in meaning to n = n + 1.
Control
C++ provides a number of elementary control structures,
directly inherited from C.
See slide [cc-control].
Control
- conditional -- if (b) S1; else S2;
- selection -- switch(n) { case n1: S1; break; ... default: ... }
- iteration -- while (b) S
- looping -- for( int i = 1; i <= MAX; i + + ) S
- jumps -- return, break, continue, goto
slide: C++ -- control
These include a
conditional statement
(of which the else part may be omitted),
a selection statement
(that allows for a default branch),
an iteration statement
(which is also offered in a reversed form
to allow a repeat),
a loop statement
(consisting of an initialization part, a part
to test for termination, and a repetition part to increase
the loop variable)
and, finally, jumps
(including the so much despised goto).
Objects
Despite the (at first sight) overwhelming possibilities
of defining values and control,
the essence of programming in C++ must be the development
of the abstract data types.
To illustrate the difference between C and C++, let us first look
at the realization of abstract data type in a procedural
way in a C style (employing references),
and then at the realization in C++ employing
the class construct.
Note that in plain C, pointers must be used instead
of references.
ADT in C style
struct ctr { int n; }
void ctr_init(ctr& c) { c.n = 0; }
void ctr_add(ctr& c, int i) { c.n = c.n + i; }
int ctr_val(ctr& c) { return c.n; }
Usage
ctr c; ctr_init(c); ctr_add(c,1);
ctr* p = new ctr; ctr_init(*p); ctr_add(*p);
slide: C++ -- objects (1)
The ctr type defined in slide [cc-objects-1] may be regarded as
a standard realization of abstract data types
in a procedural language.
It defines a data structure ctr,
an initialization function {\em ctr_init},
a function {\em ctr_add} to modify the value or state
of an element of the (abstract) type
and an observation function {\em ctr_val}
that informs us about its value.
We may either declare a ctr object or a pointer
to a ctr instance and invoke the functions as
indicated.
ADT in C++
class ctr {
public:
ctr() { n = 0; } // constructor
~ctr() { cout << "bye"; }; // destructor
void add( int i = 1) { n = n + i; }
int val( ) { return n; }
private:
int n;
};
Usage
ctr c; c.add(1); cout << c.val();
ctr* p = new ctr(); c->add(1); ...
slide: C++ -- objects (2)
In contrast, to define (the realization of) an abstract
data type in C++, we employ the class construct
and define member functions (or methods)
that operate on the data encapsulated by instances of the class.
See slide [cc-objects-2].
Inheritance
Not only is C++ an efficient language,
but it also offers features lacking in Smalltalk
and Eiffel.
In particular, it allows us to make a distinction
between (private) members of a class that are
inaccessible to everybody (including descendants),
(protected) members that are inaccessible to ordinary clients
(but not to descendants),
and (public) members that are accessible to everybody.
Inheritance
class A { ancestor
public:
A() { n = 0; }
void add( int i ) { n = n + i; }
virtual int val() { return n; }
protected: // private would deny access to D
int n;
};
class D : public A { descendant
public:
D() : A() { }
int val() { return n 2; }
};
slide: C++ -- inheritance
In the example in slide [cc-inheritance],
using private
instead of protected would deny access to
the instance variable n of A.
The example also illustrates the use of virtual functions
(to refine the observation val to deliver the
value of the object modulo two)
and the invocation of constructors of ancestor classes
(which need not be explicitly specified by the user).
Allowing descendants full access to the instance variables
defined by ancestors, however,
increases the dependency on the actual
implementation of these ancestors,
with the risk of a total collapse when the implementation
of an ancestor changes.
Technology
In addition to the elements introduced thus far, C++
offers a number of other features that may profitably
be used in the development of libraries and programs.
See slide [cc-tech-1].
Techniques
- templates -- template<class T> class C { ... }
- overloading -- void read(int); void read(float)
- friends -- to bypass protection
- type conversions -- by class constructors or type operators
- type coercion -- by explicit casts (is dangerous)
- smart pointers -- by overloading de-reference
slide: C++ -- techniques (1)
For instance, C++ offers
templates
(to define generic classes and functions),
overloading
(to define a single function for multiple types),
friends
(to bypass protection),
type conversion
(which may be defined by class constructors
or type operators),
type coercions
(or casts, which may be used to resolve ambiguity
or to escape a too rigid typing regime),
and smart pointers
(obtained by overloading the dereference operator).
An integral part of standard C++ is the Standard Template Library,
offering a generic collection of containers,
of which a brief description is given in
section [STL].
To get some of the flavor of using C++, look at the definition of
the ctr class in slide [cc-tech-2] employing multiple constructors,
operators, default arguments and type conversion.
class ctr { C++
public:
ctr(int i = 0, char* x = "ctr") {
n = i; strcpy(s,x);
}
ctr& operator++(int) { n++; return *this; }
int operator()() { return n; }
operator int() { return n; }
operator char*() { return s; }
private:
int n; char s[64];
};
Usage
ctr c; cout << (char*) c++ << "=" << c();
slide: C++ - techniques (2)
The ctr provides a constructor,
with an integer argument (which is by default set to zero,
if omitted) and a string argument
(that expects a name for the counter).
The increment operator is used to define the
function add
(which by default increments by one),
and the application operator is used instead of val.
Also, a type conversion operator is defined
to deliver the value of the ctr instance anywhere where
an integer is expected.
In addition, a char* type conversion operator
is used to return
the name of the ctr.
Again, the difference is most clearly reflected in how
an instance of ctr is used.
This example illustrates that C++ offers
many of the features that allow us to define
objects which may be used in a (more or less)
natural way.
In the end, this is what software development is about,
to please the user, within reason.
Summary
This section has presented an overview of C++.
It gave an outline of its history,
and discussed the design principles underlying C++
and its heritage from C.
The language C++
C
- design principles -- efficiency
- terminology -- object, type
- syntax -- object, reference, pointer
- objects -- abstract data types
- inheritance -- virtual functions
- techniques -- operators, templates, overloading
slide: C++ -- summary
It listed the keywords that C++ introduces
in addition to the keywords employed in C
and characterized the object-oriented constructs
supported by C++.
An example was given to illustrate the difference between
realizing an abstract data type in C and realizing
the same abstract data type in C++.
Further, it illustrated the use of virtual functions
when deriving classes by inheritance,
and discussed a number of additional features
supported by C++.
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.