Part A - Introduction

Welcome to Object-Oriented

Introduce real-world applications and object-oriented programming
Introduce namespaces for grouping an application's identifiers
Write our first object-oriented program

"The technique of mastering complexity has been known since ancient times:
divide et impera (divide and rule)" (Dijkstra, 1979).

Complexity | Languages | Namespaces | I/O Example | Summary | Exercises


Real-world software applications are typically intricate, complex and dynamic.  Their number of statements may be quite large.  They may take years of programming effort to mature and may involve many developers.  Many developers build transferrable, practical and upgradeable solutions using objects.  The object-oriented paradigm offers both designers and programmers a straightforward system within which to represent the key features of many of their problem domains. 

C++ is the original object-oriented successor to the C programming language.  C++ augmented C with object-oriented facilities.  It is a high-level imperative language for implementing object-oriented solutions to programming problems.  It is clean enough to identify the basic concepts of object-oriented programming and comprehensive enough to introduce the more advanced concepts. 


Complexity

We master complexity by identifying a problem's most important features.  We categorize these features into objects and activities.  Identifying objects and identifying activities are complementary tasks. 

Consider the ordering system for a retail chain of stores shown below.  Each store

  • places orders with different suppliers
  • keeps track of outstanding orders
  • receives shipments from suppliers
  • adds instructions to special orders

algorithmic approach

Each item in this structure diagram describes a specific activity. 

Switching our orientation from these activities to the objects involved, we first identify an Order and a Special Order.  Focusing on Orders, we break each Order object into the quantity ordered and its International Article Number (EAN).  Focusing on EAN next, we break each EAN object into a country or region code, company number, item reference and check digit.  We use the GS1 prefix table published by the GS1 Global Office to extract the country or region code from the EAN. 

We say that an Order has an EAN and that an EAN uses the GS1 prefix list to determine its components.  If we attach an instruction to an Order object, we identify the Order as a Special Order. 

The diagram below shows the relationships between the objects in this ordering system.  The connectors identify the types of relationships between the objects.

class relationships

The switch in emphasis from activities in the structure chart to objects in the relationship diagram betrays our preference for an object-oriented description.  These two approaches to complexity have a long history.  They date back to the ancient Greeks.  Heraclitus viewed the world in terms of process, while Democritus viewed the world in terms of discrete atoms. 

Learning to divide a complex problem into objects and to identify the relationships between them is properly the domain of system analysis and design.  These notes prepare a foundation for that studying analysis and design by introducing the programming tools that we will use to implement object-oriented designs. 


Languages

Eric Levenez maintains a web page that lists the major programming languages throughout the world.  TIOBE Software tracks the most popular ones and long-term trends based on world-wide availability of software engineers as calculated from Google, Yahoo!, and MSN search engines.  Many of these languages support object orientation. 

C, Java, Objective-C and C++ are currently the four most popular, programming languages.  Each of these languages is an imperative language.  An imperative language specifies each step that is necessary to reach a desired state.  These four languages have much syntax in common.  Objective-C is a strict superset of C.  C++ contains almost all of C as a subset.  Java syntax is C-like, but Java is not a superset of C. 

C + + is a superset of C

Each language is distinct in its own way:

  • C has no object-oriented features.  If we use C, we have no choice but to build our solutions from activities.

  • Java is purely object-oriented.  It excludes all non-object-oriented features.  If we use Java, we have no choice but to build our solutions from objects. 

  • Objective-C is hybrid.  It augments the C language with object-oriented features.  If we use Objective-C, we can build our solutions partly from activities and partly from objects.  The main function in any Objective-C program is a C function: it is not object-oriented.  Objective-C is geared toward run-time decisions.

  • C++, like Objective-C, is hybrid.  It augments C with object-oriented features.  If we use C++, we can build our solutions partly from activities and partly from objects.  The main function in any C++ program is a C function: it is not object-oriented.  C++, unlike Objective-C, is geared toward compile-time decisions.

Features of C++

Learning C++ first has several advantages for any student who is familiar with C.  C++ is

  • nearly a superset of C
  • a multi-paradigm language
    • procedural (can focus on distinct activities)
    • object-oriented (can focus on distinct objects)
  • realistic, efficient, and flexible enough for demanding projects
    • operating systems
    • large applications
    • game programming
  • clean enough for successful learning of basic concepts
  • comprehensive enough for learning of advanced concepts

Design of C++

C++ improves type safety and results in shorter parameter lists relative to C.

Type Safety

A type-safe language traps errors at compile-time and diminishes the amount of buggy code that passes through to the client.  The compiler checks syntax with respect to type rules and generates errors or warnings wherever these rules are violated. 

C compilers are overly tolerant of type errors.  For example, a C compiler will accept the following code, which at run-time may cause a segmentation fault

 #include <stdio.h>
 void foo();

 int main(void)
 {
     foo(-25);
 }
 void foo(char x[])
 {
     printf("%s", x); /* ERROR */
 }









 Segmentation Fault (coredump)

The prototype directs the compiler to omit checking for argument/parameter type mismatches.  The argument in the function call happens to be an int of negative value (-25), while the type received in the parameter is the address of a char array.  The C compiler copies the argument into the parameter.  Since the parameter's value is not a valid address, printing from that 'address' could cause a segmentation fault. 

To check for type mismatches, we simply add the parameter type to the prototype.  Then, the compiler issues an error message like that shown on the right if the argument type does not match the parameter type. 

 #include <stdio.h>
 void foo(char x[]);

 int main(void)
 {
     foo(-25);
 }
 void foo(char x[])
 {
     printf("%s", x);
 }




 Function argument assignment between
 types "char*" and "int" is not allowed.





The C language allows both versions in order to support legacy code.  When Bjarne Stroustrup created the C++ language, legacy code was not an issue and he mandated that all prototypes list their parameter types and that all C++ compilers check for argument/parameter type mismatches at compile-time. 

Shorter Parameter Lists

Non-object-oriented languages have a natural propensity for lengthy parameter lists.  The only way for a C function to access external data (other than through global variables) isa through its parameter list.  Consider a program that receives data at its lowest level and uses that data elsewhere also at its lowest level as shown below.  The data must pass through every intermediate function as well as the topmost function, even though none of these functions use that data.  The more data that must pass through functions, the lengthier are their parameter lists. 

large parameter lists

The alternative to lengthy parameter lists is to make the two functions members of the same object that holds data privately for its functions.  This redesign flattens the function hierarchy as shown below and results in noticeably shorter parameter lists.  C++ provides the mechanism for such local sharing. 

shared private data


Namespaces

In large-scale applications chances are that different developers will use the same identifiers for different variables.  When their work is brought together naming conflicts may arise.  We avoid such conflicts by identifying each part of an application with its own unique namespace. 

A namespace is a scope, which contains the definitions of its own identifiers.  Scoping rules prevent an identifier from one namespace from conflicting with identically named identifiers from other namespaces. 

The definition of a namespace takes the form

 namespace identifier {

 }

The identifier following the keyword namespace is the name that we assign to the scope.  The pair of braces enclose the scope. 

For example, to define x in two different namespaces, we write

 namespace a {

     int x = 2;
     // ...

 }

 namespace b {

     int x = 3;
     // ...

 } 

To access a variable that is defined within a namespace, we precede its identifier with the namespace's identifier followed by a double colon (::).  We call this double colon the scope resolution operator

For example, to increment the x in namespace a and to decrement the x in namespace b, we write

     a::x++;
     b::x--;

Each namespace prefix uniquely identifies each variable.

To expose a preferred x identifier, we specify a using declaration:

 using a::x;

Afterwards, we can write:

     x++;  // increments a::x but not b::x

To expose all of the identifiers within namespace a, we specify the using directive:

 using namespace a;

Afterwards, we can write:

     x++; // increments a::x but not b::x

Exposing an identifier or a namespace adds the identifier(s) to the global namespace. 

From C to C++

Consider a program that displays the following phrase on the standard output device

 Welcome to Object-Oriented

C - procedural code

The C source code for displaying this phrase is

 // A Language for Complexity
 //  welcome.c
 //
 // To compile on linux: gcc welcome.c
 // To run compiled code: a.out
 //
 // To compile on windows: cl welcome.c
 // To run compiled code: welcome
 //

 #include <stdio.h>

 int main(void)
 {
         printf("Welcome to Object-Oriented\n"); 
 }

The two global functions - main() and printf() - do not refer to any object.  All identifiers share the global namespace.

C++ - procedural code

The procedural C++ source code for displaying our phrase is

 // A Language for Complexity
 // welcome.cpp
 //
 // To compile on linux:   g++ welcome.cpp
 //  To run compiled code: a.out
 //
 // To compile on windows:   cl welcome.cpp
 //  To run compiled code: welcome
 //

 #include <cstdio>
 using namespace std;

 int main() {
     printf("Welcome to Object-Oriented\n"); 
 }

<cstdio> is the C++ version of the C header file <stdio.h>.  The prototype for printf() is declared in the <cstdio> header file within the std namespace. 

The directive

 using namespace std;

exposes all of the identifiers declared within the std namespace.  Most identifiers associated with the standard C++ libraries are declared within this namespace. 

C++ - hybrid code

The object-oriented C++ source code for displaying our phrase is

 // A Language for Complexity
 // welcome.cpp
 //
 // To compile on linux:  g++ welcome.cpp
 // To run compiled code: a.out
 //
 // To compile on windows:   cl welcome.cpp
 //  To run compiled code: welcome
 //

 #include <iostream>
 using namespace std;

 int main ( ) {
     cout << "Welcome to Object-Oriented" << endl; 
 }

The object-oriented syntax introduced here consists of:

  1. The directive
     #include <iostream>
    
    inserts the <iostream> header file into the source code.  The <iostream> library provides access to the standard input and output objects. 

  2. The object
     cout
    
    represents the standard output device. 

  3. The operator
     <<
    
    inserts the string on the right side of the operator into the standard output object.

  4. The manipulator
     endl
    
    represents an end of line character and a flushing of the output buffer. 

Taken together, these components form the statement

 cout << "Welcome to Object-Oriented" << endl;

We say that this statement inserts into the standard output stream the string "Welcome to Object-Oriented" followed by a newline character and then flushes the output buffer.


Input and Output Example

The following object-oriented C++ program accepts an integer value from standard input and displays that value on standard output.  Our program looks something like:

 // Input Output Objects
 // inputOutput.cpp
 //
 // To compile on linux: g++ inputOutput.cpp 
 // To run compiled code: a.out
 //
 // To compile on windows:   cl welcome.cpp
 // To run compiled code: welcome
 //

 #include <iostream>
 using namespace std;

 int main() {
     int i;

     cout << "Enter an integer : ";
     cin >> i;
     cout << "You entered " << i << endl;
 }
















 Enter an integer : 65

 You entered 65

The object-oriented input statement includes:

  • The object
     cin
    
    represents the standard input device. 

  • The extraction operator
     >>
    
    extracts from the left-hand object the data identified on the operator's right side. 

Taken together, the statement gets text characters from the input stream, converts them into an integer value, and stores that value in the variable i

 cin >> i;

C++ uses the type of i to determine how to convert the text characters into bytes in memory.  Note the absence of the address of operator on i and of a conversion specifier, both of which C requires.


Summary

  • the object-oriented paradigm focuses on the objects in a problem domain
  • object-oriented programming languages are designed for solving complex problems
  • C++ is a hybrid programming language that can focus on both objects and activities
  • C++ provides improved type safety and shorter parameter lists compared to C
  • cout is the object that represents the standard output device
  • cin is the object that represents the standard input device
  • << is the operator that inserts data into the object on its left
  • >> is the operator that extracts data from the object on its left

Exercises

  • Read Wikipedia on the C++ Programming Language
  • Read this interview with Bjarne Stroustrup

    "Be adventurous in your experimentation and somewhat more cautious in your production code. On my home pages, I have a "Technical and Style FAQ" that gives many practical hints and examples. However, to really develop significant new skills, one must read articles and books. I think of C++ as a multi-paradigm programming language. That is, C++ is a language that supports several effective programming techniques, where the best solution to a real-world programming problem often involves a combination of these techniques. Thus, I encourage people to learn data abstraction (roughly, programming using abstract classes), object-oriented programming (roughly, programming using class hierarchies) and generic programming (roughly, programming using templates). Furthermore, I encourage people to look for combinations of these techniques rather than becoming fanatical about one of these paradigms because it happens to be a great solution to a few problems.

    It is important to remember that a programming language is only a tool. Once you master the basic concepts of a language, such as C++, it is far more important to gain a good understanding of an application area and of the problem you are trying to solve than it is to study the minute technical details of C++. Good luck, and have fun with C++! "

    Extract from the Linux Journal: Interview with Bjarne Stroustrup
    Posted on Thursday, August 28, 2003 by Aleksey Dolya

  • Install Visual Studio on your local computer
  • Ensure that your remote Linux account is operational



Previous Reading  Previous: Table of Contents Next: Object Terminology   Next Reading


  Designed by Chris Szalwinski   Copying From This Site   
Logo
Creative Commons License