topical media & game development

talk show tell print

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?e_1:e_2 testing the condition b to deliver e_1 when it evaluates to true and e_2 otherwise. Also, C++ allows for sequencing within expressions of the form (e_1,...,e_n), which evaluates e_1,...,e_n in that order and delivers e_n 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.