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

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.

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.

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.

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.

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
Each namespace prefix uniquely identifies each variable.
To expose a preferred x identifier,
we specify a using declaration:
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:
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
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:
-
The directive
inserts the <iostream>
header file into the source code.
The <iostream> library
provides access to the standard input and output objects.
- The object
represents the standard output device.
- The operator
inserts the string on the right side of the operator
into the standard output object.
- The manipulator
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
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
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
|