The C++ Programming
Inheritance Preview
Language
Inheritance Example: Ada-style Vectors
Dynamic Binding Preview
Overloading
New-Style Comments
A Tour Through C++
Typ e-Safe Linkage
Inline Functions
Dynamic Memory Management
Outline
Const Typ e Quali er
Stream I/O
C++ Overview
Bo olean Typ e
C++ Design Goals
References
Major C++ Enhancements
Typ e Cast Syntax
Other Enhancements
Default Parameters
Language Features Not Part of C++
Declaration Statements
Function Prototyp es
Abbreviated Typ e Names
C++ Classes
User-De ned Conversions
Class Vector Example
Static Initializ ati on
C++ Objects
Miscellaneous Di erences
C++ Object-Oriented Features
1
C++ Overview
C++ Design Goals
C++ was designed at AT&T Bell Labs by
As with C, run-time eciency is imp ortant
Bjarne Stroustrup in the early 80's
{ e.g., unlike Ada, complicated run-time libraries
{ The original cfront translated C++ into C for
have not traditionally b een required for C++
portability
However, this was dicult to debug and p o- Note, that there is no language-sp eci c sup-
tentially inecient port for concurrency, p ersistence, or distri-
bution in C++
{ Many native host machine compilers now exist
e.g.,Borland, DEC, GNU, HP, IBM, Microsoft,
Compatibility with C libraries and UNIX
Sun, Symantec, etc.
to ols is emphasized, e.g.,
{ Object co de reuse
C++ is a mostly upwardly compatible ex-
tension of C that provides:
The storage layout of structures is compat-
ible with C
1. Stronger typ echecking
Supp ort for X-windows, standard ANSI C li-
2. Supp ort for data abstraction
brary, UNIX system calls via extern blo ck
3. Supp ort for object-oriented programming
{ C++ works with the make recompilation utility
{ C++ supp orts the Object-Oriented paradigm
but do es not require it
2 3
Major C++ Enhancements
C++ Design Goals cont'd
1. C++ supp orts object-oriented program-
ming features
\As close to C as p ossible, but no closer"
e.g., single and multiple inheritance, abstract
{ i.e., C++ is not a prop er sup erset of C, so that
base classes, and virtual functions
backwards compatibility is not entirely main-
tained
Typically not a problem in practice:: :
2. C++ facilitates data abstraction and en-
capsulation that hides representations b e-
hind abstract interfaces
Note, certain C++ design goals con ict
e.g., the class mechanism and parameterized
with mo dern techniques for:
typ es
1. Compiler optimization
3. C++ provides enhanced error handling ca-
{ e.g., p ointers to arbitrary memory lo cations
pabilities
complicate register allo cation and garbage
collection
e.g., exception handling
2. Software engineering
4. C++ provides a means for identifying an
{ e.g., separate compilation complicates inlin-
object's typ e at runtime
ing due to diculty of interpro cedural anal-
ysis
e.g., Run-Time Typ e Identi cation RTTI
4 5
Other Enhancements
Other Enhancements cont'd
C++ enforces typ e checking via function
prototyp es
References provide \call-by-reference" pa-
rameter passing
Allows several di erent commenting styles
Declare constants with the const typ e qual-
Provides typ e-safe linkage
i er
Provides inline function expansion
New mutable typ e quali er
Built-in dynamic memory management via
New bool b o olean typ e
new and delete op erators
New typ e-secure extensible I/O interface
Default values for function parameters
called streams and iostreams
Op erator and function overloading
6 7
Other Enhancements cont'd
A new set of \function call"-style cast no-
Language Features Not Part of
tations
C++
Variable declarations may o ccur anywhere
1. Concurrency
statements may app ear within a blo ck
See \Concurrent C" by Nehrain Gehani
The name of a struct, class, enum, or
union is a typ e name
2. Persistence
See Exo dus system and E programming lan-
Allows user-de ned conversion op erators
guage
Static data initial i zer s maybearbitrary ex-
3. Garbage Collection
pressions
See pap ers in USENIX C++ 1994
C++ provides a namespace control mech-
anism for restricting the scop e of classes,
functions, and global objects
9 8
Function Prototyp es cont'd
Function Prototyp es
Prop er prototyp e use detects erroneous
parameter passing at compile-time, e.g.,
C++ supp orts stronger typ e checking via
function prototyp es
STDC jj de ned cplusplus if de ned
{ Unlike ANSI-C, C++ requires prototyp es for
extern int freop en const char *nm,
b oth function declarations and de nitions
const char *tp,
FILE *s;
extern char *gets char *;
{ Function prototyp es eliminate a class of com-
extern int p errorconst char *;
mon C errors
else /* Original C-style syntax. */
extern int freop en , p error ;
e.g., mismatched or misnumb ered parameter
extern char *gets ;
values and return typ es
endif /* de ned STDC */
/* :::*/
int main void f
Prototyp es are used for external declara-
char buf[80];
tions in header les, e.g.,
if freop en "./fo o", "r", stdin == 0
extern char *strdup const char *s;
p error "freop en", exit 1;
extern int strcmp const char *s, const char *t;
FILE *fop en const char * lename, const char *typ e;
while gets buf != 0
extern void print error msg and die const char *msg;
/* :::*/;
g
11 10
Overloading
Function Prototyp es cont'd
Two or more functions or op erators may
The preceeding program fails mysteriously
b e given the same name provided the typ e
if the actual calls are:
signature for each function is unique:
1. Unique argument typ es:
/* Extra argument, also out-of-order! */
freop en stdin, "new le", 10, 'C';
double square double;
Complex &square Complex &;
/* Omitted arguments. */
2. Unique numb er of arguments:
freop en "new le", "r";
void move int;
void move int, int;
A \Classic C" compiler would generally
not detect erroneous parameter passing at
A function's return typ e is not considered
compile time though lint would
when distinguishing b etween overloaded in-
stances
{ Note, C++ lint utilities are not widely avail-
able, but running GNU g++ -Wall provides
{ e.g., the following declarations are ambiguous
similartyp echecking facilities
to the C++ compiler:
extern double op erator / Complex &, Complex &;
extern Complex op erator / Complex &, Complex &;
Function prototyp es are used in b oth def-
initions and declarations
Note, overloading is really just \syntactic
{ Note, the function prototyp es must b e consis-
tent!!!
sugar!"
12 13
C++ Classes
C++ Classes cont'd
The class is the basic protection and data
abstraction unit in C++
For eciency and C compatibility reasons,
C++ has two typ e systems
{ i.e., rather than \p er-object" protection
1. One for built-in typ es, e.g., int, oat, char,
double, etc.
The class mechanism facilitates the cre-
ation of user-de ned Abstract Data Typ es
2. One for user-de ned typ es, e.g., classes, structs,
ADTs
unions, enums etc.
{ A class declarator de nes a typ e comprised of
data memb ers,aswell as metho d op erators
Note that constructors, overloading, in-
Data memb ers may b e b oth built-in and user-
heritance, and dynamic binding only apply
de ned
to user-de ned typ es
{ This minimizes surprises, but is rather cumb er-
{ Classes are \co okie cutters" used to de ne ob-
some to do cument and explain:: :
jects
a.k.a. instances
15 14
C++ Classes cont'd
C++ Classes cont'd
General characteristics of C++ classes:
A class is a \typ e constructor"
{ Any numb er of class objects may b e de ned
{ e.g., in contrast to an Ada package oraMod-
ula 2 mo dule
i.e., objects, which have identity, state, and
b ehavior
Note, these are not typ es, they are \encap-
sulation units"
{ Class objects may b e dynamically allo cated and
deallo cated
{ Until recently, C++ did not have a higher-level
mo dularization mechanism:: :
{ Passing class objects, p ointers to class objects,
and references to class objects as parameters
This was a problem for large systems, due
to functions are legal
to lack of library management facilities and
visibility controls
{ Vectors of class objects may b e de ned
{ Recent versions of the ANSI C++ draft stan-
dard include mechanisms that addresses names-
pace control and visibility/scoping, e.g.,
A class serves a similar purp ose to a C
struct
Name spaces
{ However, it is extended to allow user-de ned
Nested classes
b ehavior, as well
17 16
Class Vector Example
There are several signi cant limitati ons with
Class Vector Example cont'd
built-in C and C++ arrays, e.g.,
1. The size must be a compile-time constant,
We can write a C++ class to overcome
e.g.,
some of these limitati ons, i.e.,
void fo o int i
{ 1 compile-time constant size
f
int a[100],b[100];//OK
int c[i]; // Error!
{ 4 lack of range checking
g
2. Array size cannot vary at run-time
Later on we'll use inheritance to nish the
3. Legal array b ounds run from 0 to size 1
job, i.e.,
{ 2 resizing
4. No range checking p erformed at run-time, e.g.,
f
{ 3 non-zero lower b ounds
int a[10],i;
for i = 0; i <= 10; i++
{ 5 array assignment
a[i]= 0;
g
5. Cannot p erform full array assignments, e.g.,
a = b; // Error!
19 18
Class Vector Example cont'd
Class Vector Example cont'd
/* File Vector.h this ADT is incomplete
wrt initial i zati on and assignment:::! */
/* File Vector.C */
if !de ned VECTOR H // Wrapp er section
de ne VECTOR H
include "Vector.h"
t i, T item f bool Vector::set size
typ edef int T;
if this->in range i f
class Vector f
[i]= item; this->buf
public:
return true;
t len = 100 f Vector size
g
this->size = len;
else
= new T[len]; this->buf
return false;
g
g
~Vectorvoid f delete [] this->buf ; g
t size void const f return this->size ; g size
bool set size t i, T item;
t i, T &item const f bool Vector::get size
bool get size t i, T &item const;
if this->in range i f
[i]; item = this->buf
private: return true;
size t size ;
g
T *buf ;
else
bool in range size ticonst f
return false;
return i >= 0&&i
g
g
g;
endif /* VECTOR H*/
20 21
Class Vector Example cont'd
// File test.C
Class Vector Example cont'd
include
include "Vector.h"
t size f void fo o size
Vector user vec size; // Call constructor
int c vec[size]; // Error, no dynamic range
len dynamically allo cated memory of size len
c vec[0]= 0;
buf
user vec.set 0, 0;
for int i = 1; i < user vec.size ; i++ f
int t;
user vec.get i 1, t;
user vec.set i, t + 1;
vec[i]=c vec[i 1] +1; c
The control blo ck that represents an ob-
g
ject of class Vector
// Error, private and protected data inaccessible
{ Note, the control blo ck may be allo cated o
size = user vec.size 1;
the stack, the global data segment, or the heap
user vec.buf [size]= 100;
// Run-time error, index out of range
{ However, the buf eld always p oints to mem-
if user vec.set user vec.size , 1000 == false
ory allo cated o the heap
err "index out of range";
// Index out of range not detected at runtime!
vec[size]=1000; c
// Destructor called when user vec leaves scop e
g
22 23
Class Vector Example cont'd
Class Vector Example cont'd
/* File Vector.h */
Note that this example has several unnec-
essary limit ati ons that are addressed by
// typ edef int T;
additional C++ features, e.g.,
template
class Vector f
public:
{ set/get paradigm di ers from C's built-in sub-
struct RANGE ERROR fg;
script notation
Vector size t len = 100: size len f
if this->size <= 0
throw Vector
{ Error checking via return value is somewhat
= new T[this->size ]; else this->buf
awkward
g
~Vectorvoid f delete [] this->buf ; g
{ Only works for a vectorofints
size t size void const f return this->size ; g
T&op erator[] size tif
if this->in range i
{ Classes that inherit from Vector may not al-
[i]; return this->buf
ways want the extra overhead of range checking:: :
else throw Vector
g
protected:
tifreturn this->buf [i]; g T &elem size
The following example illustrates several
private:
more advanced C++ features
size t size ;
; T *buf
{ Don't worry,we'll cover these features in much
bool in range size tif
greater detail over the course of the class!!!!
return i >= 0&&i
g
g;
24 25
Class Vector Example cont'd
// File test.C
C++ Objects
include
include "Vector.h"
void fo o size t size f
try f // Illustrates exception handling:: :
A C++ object is an instance of a class or
vec size; // Call constructor Vector
int c vec[size]; // Error, no dynamic range
any other C++ typ e for that matter:::
c vec[0]=user vec[0]=0;
for int i = 1; i < user vec.size ; i++ f
An object can b e instantiated or disp osed
vec[i]=user vec[i 1] +1; user
c vec[i]=c vec[i 1] +1;
either implici tl y or explicitl y, dep ending on
g
its life-time
// Error, private and protected data inaccessible
size = user vec.size 1;
user vec.buf [size]= 100;
user vec.elem 3 = 120;
As with C, the life-time of a C++ object
is either static, automatic, or dynamic
ERROR thrown // Run-time error, RANGE
user vec[user vec.size ]=1000;
{ C and C++ refer to this as the \storage class"
of an object
// Index out of range not detected at runtime!
c vec[size]=1000;
// Destructor called when user vec leaves scop e
g
ERROR f /* :: :*/ g catch Vector
g
27 26
C++ Objects cont'd
C++ Objects cont'd
Life-time or \storage class:"
1. Static
{ i.e., it lives throughout life-time of pro cess
Automatic
High
Stack
Variables
Addresses
{ static can b e used for lo cal, global, or class-
sp eci c objects note, their scop e is di er-
Dynamic
ent
Heap
Variables
Uninitialized
2. Automatic
Global Data
Static
Variables
Initialized
{ i.e., it lives only during function invo cation,
Global Data
on the \run-time stack"
Low
Read-Only
Addresses
Text Co de and
Data
3. Dynamic
{ i.e., it lives between corresp onding calls to
op erators new and delete
Or malloc and free
Typical layout of memory objects in the
pro cess address space
{ Dynamic objects have life-times that extend
beyond their original scop e
29 28
C++ Objects cont'd
C++ Objects cont'd
Several workarounds exist, however, e.g.,
{ Use Ei el or LISP ;-
Most C++ implementations do not sup-
port automatic garbage collection of dy-
{ Use inheritance to derive from base class Col-
namically allo cated objects
lectible
{ In garbage collection schemes, the run-time
However, this only works then for a sub-
system is resp onsible for detecting and deal-
set of classes i.e., do esn't work for built-in
lo cating unused dynamic memory
typ es:::
{ Note, it is very dicult to implement garbage
{ Use the class-sp eci c new and delete op era-
collection correctly in C++ due to p ointers and
tors to de ne a memory management facility
unions
using reference counts to reclaim unused mem-
ory
{ Adapt Hans Bo ehm's conservative garbage col-
Therefore, programmers must explicitly deal-
lectorfor C to C++:: :
lo cate objects when they want them to go
away
{ C++ constructors and destructors are useful
No solution is optimal, however, so stor-
for automating certain typ es of memory management:: :
age management is often p erformed \by
hand" ugh ;-
31 30
C++ Object-Oriented Features
C++ Object-Oriented Features
C++ provides three characteristics gen-
cont'd
erally asso ciated with object-oriented pro-
gramming:
C++'s object-oriented features encourage
1. Data Abstraction
designs that
{ Package a class abstraction so that only the
1. Explicitly distinguish general prop erties of re-
public interface is visible and the implemen-
lated concepts from
tation details are hidden from clients
{ Allowparameterization based on typ e
2. Sp eci c details of particular instantiations of
these concepts
2. Single and Multiple Inheritance
{ A derived class inherits op erations and at-
tributes from one ormore base classes, p os-
e.g., an object-oriented graphical shap es
sibly providing additional op erations and/or
attributes
library design using inheritance and dy-
namic binding
3. Dynamic Binding
{ The actual typ e of an object and thereby
its asso ciated op erations need not b e fully
known until run-time
This approach facilitates extensibility and
reusability
Compare with C++ template feature, which
are instantiated at compile-time
33 32
C++ Object-Oriented Features
C++ Object-Oriented Features
cont'd
cont'd Inheritance and dynamic binding facilitate
Circle Triangle Rectangle
the construction of \program families" and
frameworks
{ Program families are sets of programs whose
common prop erties are so extensive that it is
advantageous to study the common prop er-
rograms b efore analyzing individual Color ties of the p
Shape memb ers 1
1 A
A framework is an integrated set of comp o-
1 {
that collab orate to pro duct a reuseable
Point 1 nents
architecture for a family of related applications
It also supp orts the op en/closed principle
Note, the \OOD challenge" is to map ar-
{ i.e., op en with resp ect to extensibility, closed
bitraril y complex system architectures into
with resp ect to stability
inheritance hierarchies
35 34
Inheritance Example: Ada-style
Inheritance Preview
Vectors
Atyp e can inherit or derive the character-
istics of another base typ e. These derived
/* File Ada Vector.h still incomplete wrt
typ es act just like the base typ e, except
assignment and initiali zat i on */
for an explicit list of:
if !de ned ADA VECTOR H
1. Op erations that are implemented di erently,
ADA VECTOR H de ne
i.e., overridden
include "Vector.h"
template
2. Additional op erations and extra data memb ers
Vector: private Vector
f
public:
3. Mo di ed metho d access privileges
Vectorint l, int h; Ada
T&op erator int i;
C++ supp orts b oth single and multiple
// extend visibility from class Vector
inheritance, e.g.,
Vector::size;
ERROR; Vector::RANGE
class X f /* :::*/ g;
// Note, destructorisnot inherited:: :
class Y:public X f /* :::*/ g;
private:
class Z: public X f /* :::*/ g;
int lo bnd ;
class YZ : public Y, public Z f /* :: :*/ g;
g;
endif /* ADA VECTOR H*/
36 37
Inheritance Example: Ada-style
Vectors cont'd
Inheritance Example: Ada-style
Example Ada Vector Usage
Vectors cont'd
{ // File main.C
include
/* File Ada Vector.C */
include "Ada Vector.h"
extern "C" int atoi const char *;
template
int main int argc, char *argv[] f
Ada Vector
try f
: lo bnd l, Vector
int lower = atoi argv[1];
int upp er = atoi argv[2];
Ada Vector
template
T &Ada Vector
ada vec lower = 0;
if this->in range i this->lo bnd
// Call inherited op eration, no range checking
for int i = lower+1;i<= ada vec.size ; i++
return this->elem i this->lo bnd ;
ada vec i = ada vec i 1+1;
else
throw Ada Vector
// Run-time error, index out of range
/* or
ada vec upp er + 1 = 100;
*this[i this->lo bnd ];*/
g
// Vector destructor called when
vec go es out of scop e // ada
g
catch Ada Vector
g
39 38
Dynamic Binding Preview
Dynamic Binding Preview
cont'd
Dynamic binding is a mechanism used along
e.g.,
with inheritance to supp ort a form of p oly-
morphism
struct X f /* Base class */
int fvoid f puts "X::f"; g // Non-virtual
virtual int vf void f puts "X::vf"; g // Virtual
C++ uses virtual functions to implement
g;
dynamic binding:
struct Y:public X f /* Derived class */
int fvoid f puts "Y::f"; g // Non-virtual
{ The actual metho d called at run-time dep ends
virtual int vf void f puts "Y::vf"; g // Virtual
on the class of the object used when invoking
the virtual metho d
g;
void fo o X *x f /* Note, can also use references:::*/
x->f ; /* direct call: f 1X x; */
C++ allows the class de ner the choice
x->vf ; /* indirect call: *x->vptr[1] x */
of whether to make a metho d virtual or
g
not
int main void f
{ This leads to time/space p erformance vs. ex-
ibility tradeo s
Xx;
Yy;
Virtual functions intro duce a small amount
fo o &x; // X::f, X::vf
of overhead for each virtual function call
fo o &y; // X::f, Y::vf
g
41 40
New-Style Comments
Dynamic Binding Preview
cont'd
C++ allows two commenting styles:
1. The traditional C bracketed comments, which
Each class with 1 or more virtual func-
may extend over any numb er of lines, e.g.,
tions generates one ormore virtual tables
vtables
/*
This is a multi-line C++ comment
*/
{ Note, multiple inheritance creates multiple vta-
bles
2. The new \continue until end-of-line" comment
style, e.g.,
// This is a single-line C++ comment
A vtable is logically an array of p ointers
to metho ds
Note, C-style comments do not nest
{ A vtable is typically implemented as an array
/*
of p ointers to C functions
/* Hello world program */
int main void f
printf "hello world\n";
g
Each object of a class with virtual func-
*/
tions contains one or more virtual p oint-
ers vptrs, which p oint at the appropriate
However, these two styles nest, so it is
vtable for the object
p ossible to comment out co de containing
other comments, e.g.,
{ The constructor automatically assigns the vp-
trs to p oint to the appropriate vtable
/* assert i < size // check index range */
// if i != 0 /* check for zero divide */ && 10 / i
43 42
New-Style Comments cont'd
Typ e-Safe Linkage
Naturally, it is still p ossible to use C/C++
prepro cessor directives to comment out
Typ e-safe linkage allows the linker to de-
blo cks of co de:
tect when a function is declared and/or
used inconsistently, e.g.,:
if 0
/* Make sure only valid C++ co de go es here! */
// File abs.c
/* i.e., don't use ap ostrophes! */
long abs long arg
endif
f
return arg < 0? -arg : arg;
Beware of subtle whitespace issues:: :
g
int b = a //* divided by 4 */4;
// File application.c
-a;
include
/* C++ prepro cessing and parsing. */
int abs int arg;
int b = a -a;
int main void f printf "d\n", abs 1; g
/*Cprepro cessing and parsing. */
int b = a/4; -a;
Without typ e-safe linkage, this errorwould
remain hidden until the application was
Note, in general it is b est to use whites-
ported to a machine where ints and longs
pace around op erators and other syntactic
were di erent sizes
elements, e.g.,
{ e.g., Intel 80286
char *x;
int fo o char * = x; // OK
int barchar*=x; // Error
44 45
Typ e-Safe Linkage cont'd
Typ e-Safe Linkage cont'd
Typ e-safe linkage enco des all C++ func-
Name mangling was originally created to
tion names with the typ es of their argu-
supp ort overload resolution
ments a.k.a. \name mangling"!
Only function names are mangled
e.g.,
{ i.e.,variables, constants, enums, and typ es are
not mangled:: :
long abs long arg ! abs Fl
int abs int arg ! abs Fi
On older C++ compilers, diagnostic mes-
Therefore, the linker may be used to de-
sages from the linker are sometimes rather
tect mismatches between function proto-
cryptic!
typ es, function de nitions, and function
{ See the c++filt program:: :
usage
47 46
Typ esafe Linkage cont'd
Typ esafe Linkage cont'd
Language interop erability issues
{ This problem arises as a side e ect of using
Language interop erability issues cont'd
typ e-safe linkage in C++
{ Other syntactic forms of extern blo cks:
{ C functions used in C++ co de e.g., standard
UNIX library functions must be explicitly de-
extern "C" f
clared as requiring C linkage i.e., names are
char *mktemp const char *;
not mangled via the new extern "C" declara-
char *getenv const char *;
tion
g
{ Encapsulating existing header les
e.g.,
if de ned cplusplus
extern "C" f
cplusplus */ endif /*
extern "C" int abs int i;
include
double abs double d;
ifdef cplusplus
Complex abs Complex &c;
g
cplusplus */ endif /*
int fo o int bar f
{ Note, extern blo cks also supp ort other languages:: :
cout << abs Complex 10, 4.5;
// calls abs F7Complex
e.g.,FORTRAN, Pascal, Ada, etc.
<< abs bar // calls abs
<< abs 3.1416 // calls abs Fd
g
48 49
Inline Functions
Inline Functions cont'd
Many programming languages force devel-
op ers to cho ose between:
Here's an example of a common C prob-
lem with the prepro cessor:
1. Mo dularity/abstraction function call
{ Classic C macro, no sanity-checking at macro
2. Performance macro or inline-expansion by-hand
expansion time
de ne SQUAREX X * X
int a = 10;
C++ allows inline function expansion, which
has several advantages:
int b = SQUARE a++; // trouble!!! a++*a++
1. It combines the eciency of a macro with the
typ e-security and abstraction of a function call
{ C++ inline function template
2. It reduces b oth execution time and co de size
template
p otentially
T square T x f return x*x;g
3. It discourages the traditional reliance up on macro
int c = square a++; // OK
prepro cessor statements
50 51
Inline Functions cont'd Inline Functions cont'd
Points to consider ab out inline functions:
As an example of inlining in C++, we
will discuss a simple run-time function call
1. Class metho ds that are de ned in their decla-
\trace" facility
ration are automatically expanded inline
{ Provides a rudimentary debugging facility
2. It is dicult to debug co de where functions
have b een inline expanded and/or optimized
e.g., useful for long-running network servers
3. Compilers require more time and space to com-
pile when there are many inline functions
The goals are to be able to:
4. Inline functions do not have the pseudo-p olymorphic
prop erties of macros
1. Determine the dynamic function calling b ehav-
ior of the program, i.e., \tracing"
{ However, inline templates approximate this
functionality
2. Allowfor ne-grain control over whether trac-
5. Compilers often have limits on the size and
ing is enabled, e.g.,
typ e of function that can b e inlined.
{ At compile-time remove all traces of Trace
{ e.g., if stack frame is very large:
and incur no run-time p enalty
int fo o void f
int lo cal array[1000000];
{ At run-time via signals and/or command-
// :: :
line options
{ This can cause surprising results wrt co de
size, e.g.,
3. Make it easy to automate source co de instru-
mentation
int barvoid f fo o ; fo o ; g
53 52
Inline Functions cont'd
Example output:
CC -D__INLI NE __ main.C trace.C
a.out 10 1
enter int main int argc, char *argv[] in file main.C on line 25
enter void foo void file main.C, line 8
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
{ e.g., write a regular expression to match func-
enter void foo void in file main.C, line 8
tion de nitions and then insert co de auto-
enter void foo void in file main.C, line 8
matically
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
enter void foo void in file main.C, line 8
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave void foo void
leave int main int argc, char *argv[] 54
Inline Functions cont'd
Inline Functions cont'd
// Trace.h
e.g., main.C
if !de ned TRACE H
de ne TRACE H
include "Trace.h"
if de ned NTRACE // compile-time omission
de ne TX
else
void fo o int max depth f
de ne TX Trace X, LINE , FILE
T "void fo o void";
endif /* NTRACE */
"void fo o void", 8, "main.c" */ /* Trace
depth > 0 fo o max depth 1; if max
class Trace f
/* Destructor called automatically*/
public:
g
Trace char *n, int line = 0, char * le = "";
~Trace void;
static void start tracing void;
int main int argc, char *argv[] f
static void stop tracing void;
DEPTH = const int MAX
static int set nesting indent int indent;
argc == 1? 10 : atoi argv[1];
private:
static int nesting depth ;
if argc > 2
static int nesting indent ;
nesting indent atoi argv[2]; Trace::set
static int enable tracing ;
if argc > 3
char *name ;
tracing ; Trace::stop
g;
T "int main int argc, char*argv[]";
if de ned INLINE
de ne INLINE inline
fo o MAX DEPTH;
include "Trace.i"
return 0;
else
/* Destructor called automatically*/
de ne INLINE
g
endif /* INLINE */
endif /* TRACE H*/
55 56
Inline Functions cont'd
Inline Functions cont'd
e.g., /* Trace.C */
e.g., /* Trace.i */
include "Trace.h"
if !de ned INLINE
include
include "Trace.i"
INLINE
endif /* INLINE */
Trace::Trace char *n, int line, char * le f
if Trace::enable tracing
fprintf stderr, "*senter s le s, line d\n",
/* Static initializations */
Trace::nesting indent *
int Trace::nesting depth = 0;
Trace::nesting depth ++,
int Trace::nesting indent = 3;
"", this->name = n, le, line;
int Trace::enable tracing = 1;
g
void Trace::start tracing void
INLINE
Trace::enable tracing = 1;
Trace::~Trace void f
g
if Trace::enable tracing
void Trace::stop tracing void f
fprintf stderr, "*sleave s\n",
Trace::enable tracing = 0;
Trace::nesting indent *
g
--Trace::nesting depth ,
int Trace::set nesting indent int indent f
"", this->name ;
int result = Trace::nesting indent ;
g
indent = indent; Trace::nesting
return result;
g
57 58
Dynamic Memory Management Const Typ e Quali er
Dynamic memory management is now a C++ data objects and metho ds are qual-
built-in language construct, e.g., i able with the keyword const, making
them act as \read-only" objects
{ Traditional C-style
{ e.g., placing them in the \text segment"
t; void *mallo c size
void free void *;
{ const only applies to objects, not to typ es
// :: :
int *a = mallo c 10 * sizeof *a;
free void * a;
{ C++ syntax
e.g.,
int *a = new int[10];
const char *fo o = "on a clearday";
int *b = new int;
char *const bar = "you can C forever!";
// :: :
const char *const zippy = "yow!";
delete [] a;
delete b;
fo o = "ToC or not to C?" // OK
fo o[7]='C'; // error, read-only lo cation
Built-in supp ort for memory management
improves:
// error, can't assign to const p ointer bar
bar = "avoid cliches like the plague.";
1. Typ e-security
// OK, but b e careful of read-only memory!!!
bar[1]= 'D';
2. Extensibility
const int index = 4 3; // index == 1
3. Eciency
// read-only an array of constant ints
const int array[index + 3]= f2, 4, 8, 16g;
60 59
Const Typ e Quali er cont'd
Const Typ e Quali er cont'd
User-de ned const data objects:
const metho ds
{ A const quali er can also be applied to an
{ const metho ds may sp ecify that certain read-
object of a user-de ned typ e, e.g.,
only op erations take place on user-de ned const
objects, e.g.,
const String string constant "Hi, I'm read-only!";
zero 0.0, 0.0; const Complex complex
class String f
string constant = "This will not work!"; // ERROR
public:
zero += Complex 1.0; // ERROR complex
size t size void const f return this->len ; g
complex zero == Complex 0.0; // OK
t index, char new char; void set size
// :: :
private:
Ensuring \const correctness" is an imp or-
t len; size
tant asp ect of designing C++ interfaces,
g;
e.g.,
const String string constant "hello";
1. It ensures that const objects may be passed
string constant.size ; // Fine
as parameters
{ A const metho d may not directly mo dify its
this p ointer
2. It ensures that data memb ers are not acciden-
tally corrupted
string constant.set 1, 'c'; // Error
61 62
Stream I/O
Stream I/O cont'd
C++ extends standard C library I/O with
The stream and iostream class categories
stream and iostream classes
replace stdin, stdout, and stderr with cout,
cin, and cerr
Several goals
1. Typ e-Security
These classes may b e used by overloading
the << and >> op erators
{ Reduce typ e errors for I/O on built-in and
user-de ned typ es
{ C++ do es not get a segmentation fault since
the "correct" function is called
2. Extensibility b oth ab ove and b elow
include
{ Allow user-de ned typ es to interop erate syn-
char *name = "jo e";
tactically with existing printing facilities
int id = 1000;
cout << "name = " << name << ", id = " << id << '\n';
Contrast with printf/scanf-family
// cout.op erator<< "name = ".op erator<< "jo e":::
{ In contrast, old C-style I/O o ers no protection
{ Transparently add new underlying I/O de-
from mistakes, and gets a segmentation fault
vices to the iostream mo del
on most systems!
i.e., share higher-level formatting op era-
printf "name =s, id =s\n", name, id;
tions
63 64
Bo olean Typ e
C++ has added a new build-in typ e called
Stream I/O cont'd
bool
{ The bool values are called true and false
Be careful using Stream I/O in construc-
tors and destructors for global or static
{ Converting numeric or p ointer typ e to bool
takes 0 to false and anything else to true
objects, due to unde ned linking order and
elab oration problems:::
{ bool promotes to int, taking false to 0 and
true to 1
In addition, the Stream I/O approach do es
{ Statements such as if and while are now con-
not work particularly well in a multi-threaded
verted to bool
environment:::
{ This is addressed in newer compilers that o er
{ All op erators that conceptually return truth
thread-safe iostream implementations
values return bool
e.g., the op erands of &&, jj, and !, but not
&, j, and ~
65 66
References
References cont'd
C++ allows references, which may be:
e.g., consider a swap abstraction:
1. Function parameters
2. Function return values
void swap int x, int y
f
3. Other objects
int t = x; x = y; y = t;
g
A reference variable creates an alternative
int main void f
int a = 10, b = 20;
name a.k.a. \alias" for an object
printf "a =d, b =d\n", a, b;
swap a, b;
printf "a =d, b =d\n", a, b;
References may be used instead of p oint-
g
ers to facilitate:
1. Increased co de clarity
There are several problems with this co de
2. Reduced parameter passing costs
1. It do esn't swap!
3. Better compiler optimizations
2. It requires a function call
References use call-by-value syntax, but
3. It only works for integers!
p ossess call-by-reference semantics
67 68
References cont'd
References cont'd
e.g., swap
e.g., swap
template
void swap int *xp, int *yp f
swap T &x, T &y f
int t = *xp; *xp = *yp; *yp = t;
Tt=x;
g
x = y;
int main void f
y = t;
int a = 10, b = 20;
g
printf "a =d, b =d\n", a, b;
swap &a, &b;
printf "a =d, b =d\n", a, b;
int main void f
g
int a = 10, b = 20;
double d = 10.0, e = 20.0;
de ne SWAPX,Y,T \
do fT = X; X = Y; Y = ;g while 0
printf "a =d, b =d\n", a, b;
int main void f
printf "d =f, e =e\n", d, e;
int a = 10, b = 20;
swap a, b;
printf "a =d, b =d\n", a, b;
swap d, e;
SWAP a, b, int; // b eware of a++!
printf "a =d, b =d\n", a, b;
printf "a =d, b =d\n", a, b;
printf "d =f, e =e\n", d, e;
g
g
70 69
References cont'd
Typ e Cast Syntax
ir i
10
C++ intro duces a new typ e cast syntax
in addition to Classic C style casts. This
"function-call" syntax resembles the typ e
conversion syntax in Ada and Pascal, e.g.,
With references as with classes, it is im-
// function prototyp e from math.h library
portant to distinguish initial i zati on from
extern double log10 double param;
assignment, e.g.,
if int log10 double 7734 != 0
int i = 10;
// initialization of ir
;/*Cstyle typ e cast notation */
int &ir = i; // Equivalent to int *const ip = &i;
ir = ir + 10; // dereference is automatically done
// *ip = *ip + 10;
if int log10 double 7734 != 7734
; // C++ function-style cast notation
Once initial i zed, a reference cannot b e changed
{ i.e., it may not be reassigned to reference a
This \function call" is p erformed at com-
new lo cation
pile time
{ Note, after initialization all op erations a ect
the referenced object
i.e., not the underlying const p ointer:::
71 72
Typ e Cast Syntax cont'd
Typ e Cast Syntax cont'd
This typ e cast syntax is also used to sp ec-
ify explicit typ e conversion in the C++
class mechanism
Note, there are a variety of syntactical
metho ds for constructing objects in C++,
{ This allows multiple-argument casts, i.e., \con-
e.g.,
structors"
1. Complex c1 = 10.0;
2. Complex c2 = Complex 10.0;
e.g.,:
3. Complex c3 = Complex 10.0;
class Complex f
public:
Complex double, double = 0.0;
4. Complex c4 10.0;
// :::
private:
double real, imaginary;
g;
I recommend version 4 since it is the most
consistent and also works with built-in typ es:::
// Convert 10.0 and 3.1416 into a Complex object
{ It also generalizes to multiple-argument casts:::
Complex c = Complex 10.0, 3.1416;
// Note that old-style C syntax would not suce here:::
Complex c = Complex 10.0, 3.1416;
73 74
Default Parameters cont'd
Default Parameters
Default parameter passing semantics are
similar to those in languages like Ada:
C++ allows default argument values in
function de nitions
{ e.g., only trailing arguments may have defaults
{ If trailing arguments are omitted in the actual
/* Incorrect */
function call these values are used by default,
int xint a = 10, char b, double c = 10.1;
e.g.,
{ Note, there is no supp ort for \named parame-
ter passing"
void assign grade char *name, char *grade = "A";
// additional declarations and de nitions:::
However, it is not p ossible to omit argu-
assign grade "Bjarne Stroustrup", "C++";
ments in the middle of a call, e.g.,
// Bjarne needs to work harder on his tasks
extern int fo o int = 10, double = 2.03, char = 'c';
grade "Jean Ichbiah"; assign
// Jean gets an "A" for Ada!
fo o 100, , 'd'; /* ERROR!!! */
fo o 1000; /* OK, calls fo o 1000, 2.03, 'c';
Default arguments are useful in situations
when one must change a class without af-
There are several arcane rules that p er-
fecting existing source co de
mit successive redeclarations of a func-
{ e.g., add new params at end of argument list
tion, each time adding new default argu-
and give them default values
ments
76 75
Declaration Statements cont'd
Declaration Statements
The following example illustrates declara-
C++ allows variable declarations to o ccur
tion statements and also shows the use of
anywhere statements o ccur within a blo ck
the \scop e resolution" op erator
{ The motivations for this feature are:
include
struct Foo f static int var; g;
1. To lo calize temp orary and index variables
int Fo o::var = 20;
SIZE = 100; const int MAX
2. Ensure prop er initialization
int var = 10;
{ This feature helps prevent problems like:
int main void f
int k;
f
k = call something ;
int i, j;
// Note the use of the \scop e resolution" op erator
/* many lines of co de:::*/
// :: to access the global variable var
// Oops, forgot to initialize!
int var = ::var k+Fo o::var;
while i < j /* :: :*/;
g
for int i = var; i < MAX SIZE; i++
{ Instead, you can use the following
for int j = 0; j < MAX SIZE; j++ f
int k = i* j;
f
cout << k;
for int i = x, j = y; i < j;
double var = k + ::var * 10.4;
/* :::*/;
cout << var;
g
g
g
78 77
Abbreviated Typ e Names
Declaration Statements cont'd
Unlike C, C++ allows direct use of user-
de ned typ e tag names, without requiring
However, the declaration statement fea-
apreceding union, struct, class,orenum
ture may encourage rather obscure co de
sp eci er, e.g.,
since the scoping rules are not always in-
struct Tree No de f /*Ccode*/
tuitive or desirable
int item ;
struct Tree No de *l child ,* child ;
g;
Note, new features in ANSI C++ allow
struct Tree No de f /* C++ co de */
int item ;
de nitions in the switch, while, and if
Tree No de *l child ,*r child ;
g
condition expressions:: :
Another way of lo oking this is to say that
C++ automatically typ edefs tag names,
According to the latest version of the ANSI/ISO
e.g.,
C++ draft standard, the scop e of the def-
inition of i in the following lo op is limit ed
to the body of the for lo op:
typ edef struct Tree No de Tree No de;
Note, this C++ feature is incompatible
f
with certain Classic and ANSI C identi er
for int i = 0; i < 10; i++
naming conventions, e.g.,
/* :::*/;
for int i = 0; i < 20; i++
struct Bar f /* :::*/ g;
/* :::*/;
struct Foo fg;
g
typ edef struct Foo Bar; // Illegal C++, legal C!
80 79
User-De ned Conversions
User-De ned Conversions
cont'd
The motivation for user-de ned conver-
Conversions come in two avors:
sions are similar to those for op erator and
function overloading
1. Constructor Conversions:
{ e.g., reduces \tedious" redundancy in source
{ Create a new object from objects of existing
co de
typ es
2. Conversion Op erators:
{ However, b oth approaches have similar prob-
lems with readability:: :
{ Convert an existing object into an object of
another typ e
User-de ned conversions allow for more
natural lo oking mixed-mo de arithmetic for
e.g.,
user-de ned typ es, e.g.,:
class Complex f
Complex a = Complex 1.0;
public:
Complex b = 1.0; // implicit 1.0 -> Complex 1.0
Complex double; // convert double to Complex
op erator String ; // convert Complex to String
// :::
a = b + Complex 2.5;
g;
a = b + 2.5 // implicit 2.5 -> Complex 2.5
int fo o Complex c f
c = 10.0; // c = Complex 10.0;
String s = c; // c.op erator String ;
String s = a; // implicit a.op erator String
cout << s;
g
81 82
Static Initializati on
User-De ned Conversions
In C, all initiali zat ion of static objects must
cont'd
use constant expressions, e.g.,:
int i = 10 + 20; /* le scop e */
In certain cases, the compiler will try a
int fo o void f
single level of user-de ned conversion to
static int j = 100 * 2 + 1; /* lo cal scop e */
determine if a typ e-signature matches a
g
particular use, e.g.,
However, static initiali z ers can be com-
class String f
prised of arbitrary C++ expressions, e.g.,
public:
String const char *s;
extern int fo o void; // le scop e
String &op erator += const String &;
int a = 100;
g;
int i = 10 + fo o ;
String s;
int j = i+ *new int 1;
s += "hello"; // s += String "hello";
int fo o void f
static int k = fo o ;
Note, it is easy to make a big mess by
return 100 + a;
abusing the user-de ned conversion lan-
g
guage feature:::
{ Esp ecially when conversions are combine with
Note, needless to say, this can b ecome
templates, inheritance virtual functions, and
overloading, etc.
rather cryptic, and the order of initiali z a-
tion is not well de ned between mo dules
84 83
Miscellaneous Di erences
In C++, sizeof 'a' == sizeof char; in
Miscellaneous Di erences
C, sizeof 'a' == sizeof int
cont'd
{ This facilitates more precise overloading:: :
In C++, a struct or class is a scop e; in
C a struct, enum, or enum literal are
char str[5]= "hello" is valid C, but C++
exp orted into the \global scop e," e.g.,
gives error b ecause initiali z er is to o long
b ecause of hidden trailing '\0'
struct Foo f enum Bar fBAZ, FOOBAR, BIZBUZZg; g;
/* Valid C, invalid C++ */
enum Barbar=BAZ;
// Valid C++, invalid C
In C++, a function declaration int f;
Fo o::Barbar=Fo o::BAZ;
means that f takes no arguments same
as int fvoid;. In C it means that f can
take any numb er of arguments of any typ e
The typeofanenum literal is the typ e of
at all!
its enumeration in C++; in C it is an int,
e.g.,
{ C++ would use int f:::;
/* True in C, not necessarily true in C++. */
sizeof BAZ == sizeof int;
In C++, a class may not have the same
/* True in C++, not necessarily true in C. */
sizeof Fo o::BAZ == sizeof Fo o::Bar;
name as a typ edef declared to refer to a
di erent typ e in the same scop e
85 86
Miscellaneous Di erences
Summary
cont'd
C++ adds many, many, many new fea-
In ANSI C, a global const has external
linkage by default; in C++ it has internal
tures to the C programming language
linkage, e.g.,
/* In C++, \global1" is not visible to other mo dules. */
It is not necessary to use all the features
const int global1 = 10;
/* Adding extern makes it visible to other mo dules. */
in order to write ecient, understandable,
extern const int global2 = 100;
portable applications
In ANSI C, a void * may be used as the
right-hand op erand of an assignment or
C++ is a \moving target"
initial i zati on to a variable of any p ointer
typ e, whereas in C++ it may not without
{ Therefore, the set of features continues to change
using a cast:::
and evolve
t; void *mallo c size
{ However, there areacore set of features that
/* Valid C, invalid C++ */
are imp ortant to understand and are ubiquitous
int *i = mallo c 10 * sizeof *i;
/* Valid C, valid C++ */
int *i = int * mallo c 10 * sizeof *i;
87 88