The C++ Language The C++ Language
Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program organization together with C’s efficiency and flexibility for systems programming.
Prof. Stephen A. Edwards
Copyright © 2001 Stephen A. Edwards All rights reserved
C++ Features
Example: A stack in C !#" $% &'" ( )"
Classes •
User-defined types
Operator overloading •
Copyright © 2001 Stephen A. Edwards All rights reserved
Programmer could inadvertently create )+*, -/. uninitialized stack. )0*1" 324-/ )+*.5 6678-9 $: 7 -/) . .'" ;=< 02?>@" / , % 1"
Pass-by-reference function arguments
Virtual Functions •
Dispatched depending on type at run time
Templates •
Does not help for stack that is automatic variable.
Attach different meaning to expressions such as a + b
References •
Creator function ensures stack is created properly.
Macro-like polymorphism for containers (e.g., arrays)
(
Exceptions Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
Example: A stack in C
C++ Solution: Class
A=,37- A)0*. $ B-= +2C>.C7-=DE % 67=FG=.@" / , % ;9
OPRQSTSVUHWHQOXZY O9[RQ\]S ^_UT`a=bcd e9f WZSTgd
Definition of both representation and operations
gThTi9P e Oj
Public: visible outside the class
-)0*AKLA=, I . I 7 $ J $ B-= +2 2? ,=.C7 - DM I 8/ 6 7F8G=.'" ;=< H N N!+2 I " ( Not clear these are the only stackrelated functions. Another part of program can modify any stack any way it wants to, destroying invariants. Temptation to inline these computations, not use functions. Copyright © 2001 Stephen A. Edwards All rights reserved
r d
UTWTQ/OX=kmlLYnSTgpoZqAdsr Constructor: initializes tu eHv gHh/S[=kwO[xQ\ytlzY eT{ kmS/gpoToZU/`a=bl}|\T\wu\/kx~RuHt| \ { PxuRld S^STg//cpo}t,d r O9[RQ\]gugkwlY eT{ kmS/gpoToVqlV| \T\mu\/kR~Rh fxv | \ { PRuxld \|HW/h=\ f S^m
H
HSTgTcd r Member functions see object fields like local variables Copyright © 2001 Stephen A. Edwards All rights reserved
1
C++ Stack Class
C++ Stack Class
Natural to use
Members (functions, data) can be public, protected, or private
)?=@" x A - xx.#" ,-R.'" A=, +2 x7-/.@" )+* A)32 % =F A)" );=< - .#" ) ;9
class Stack { char s[SIZE]; public: char pop(); }; Stack st; st.s[0] = ‘a’; st.pop();
Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
Class Implementation
Operator Overloading
C++ compiler translates to C-style implementation C++
Equivalent C implementation
6A+ )? =83 , !'" $% '" 6 $
)A-. I 7 $ C A- ,.@" =8 7-/.'" ( "
, ? )J !#" $% '" ( "
For manipulating user-defined “numeric” types
75 6 J - K=.@KL 8-9.'" 75 6 J 2 N#" 2 N1"
I 7 $ , ),-/)*.@" I 7 $ , A-9 A) *'K =9.'" A=,0 ,7,-/ )*.'"
Promote 2.3 to a complex number here
Copyright © 2001 Stephen A. Edwards All rights reserved
Example: Complex number type
References Designed to avoid copying in overloaded operators
C++’s operator overloading makes it elegant
6 7 5 6 7 6 'K $ 5 " 6 $
7 5 6 -/76 .@" 7 5 6 -/7 6'KL76.'" ( "
A mechanism for calling functions pass-by-reference C only has pass-by-value Pass-by-reference reduces copying
7 5 6 J7 , 7TN 21-/ 7 % J 7 56 .'"
void swap(int x, int y) {
/* Doesn’t work */
int tmp = x; x = y; y = tmp; } void swap(int &x, int &y) {
Operator overloading defines arithmetic operators for the complex type Copyright © 2001 Stephen A. Edwards All rights reserved
Creating objects of the user-defined type
Want + to mean something different in this context
Copyright © 2001 Stephen A. Edwards All rights reserved
// Error: sp is private // OK
/* Works with references */
int tmp = x; x = y; y = tmp; } Copyright © 2001 Stephen A. Edwards All rights reserved
2
Complex Number Type Member functions including operators can be defined inside or outside the class definition
(
75 6 75 6 7,97/N 2-/7 % J 75 6 A . /+N2?/'" $ C 5 N2? $ 5@" / , % * $ "
Complex Number Class Operators can also be defined outside classes
(
75 6 C7,/78HN#-/7 7 7 5 6 5?2? " 0N2 '" / , % 5@"
Copyright © 2001 Stephen A. Edwards All rights reserved
Function Overloading
% = % =
7 56 J'K 7 56 .
// Copy constructor // invoke Complex::operator +=
Copyright © 2001 Stephen A. Edwards All rights reserved
Const
Overloaded operators a specific case of overloading
Access control over variables, arguments.
General: select specific method/operator based on name, number, and type of arguments
Provides safety
Rock of Gibraltar
const double pi = 3.14159265; // Compile-time constant void foo(int); void foo(int, int);
// OK
void foo(char *);
// OK
int foo(char *);
// BAD: return type not in signature
int foo(const char* a) { *a = ‘a’; }
class bar { // “object not modified” int get_field() const { return field; } }
Copyright © 2001 Stephen A. Edwards All rights reserved
Templates
// Constant argument // Illegal: a is const
Copyright © 2001 Stephen A. Edwards All rights reserved
Template Stack Class
Our stack type is nice, but hard-wired for a single type of object
W/|9gPRQTW/|OPRQ/SHSzO/PQ/STSVUW/Q/OXZY LS^UT`Ra bcd e9f WZSTgd
Using array of “void *” or a union might help, but breaks type safety
gThTi9P e Oj Used like a type within
C++ solution: a template class Macro-processor-like way of specializing a class to specific types Mostly intended for container classes Standard Template Library has templates for •
strings, lists, vectors, hash tables, trees, etc.
Copyright © 2001 Stephen A. Edwards All rights reserved
T is a type argument
r d
UTWTQ/OX=kmlLYnSTgpoZqAdsr the body tu eHv gHh/S[=kVt9lY eT{ kmS/gpoToZU/`a=bl}|\T\wu\/kx~RuHt| \ { PxuRld S^STg//cpo}t,d r LgHu/gkmlLY eT{ kmS/gpoToVqlV| \T\mu\/kR~Rh fxv | \ { PRuxld \|HW/h=\ f S^m
H
HSTgTcd r Copyright © 2001 Stephen A. Edwards All rights reserved
3
Using a template Stack
cs;
Display-list example
// Instantiates the specialized code
cs.push(‘a’);
Say you want to draw a graphical scene List of objects •
char c = cs.pop();
lines, arcs, circles, squares, etc.
How do you store them all in a single array? Stack<double *> dps;
void *list[10];
// Ugly: type-unsafe
double d; How do you draw them all?
dps.push(&d);
switch (object->type) { case LINE: /* … */ break; case ARC: /* … */ break; } Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
Inheritance
Inheritance
Inheritance lets you build derived classes from base classes class Shape { /* … */ }; class Line : public Shape { /* … */ };
// Also a Shape
class Arc : public Shape { /* … */ };
// Also a Shape
class Shape { double x, y; // Base coordinates of shape public: void translate(double dx, double dy) { x += dx; y += dy; } Line inherits both the }; representation and
Line l; l.translate(1,3); Copyright © 2001 Stephen A. Edwards All rights reserved
Add new fields to the end of the object Fields in base class at same offset in derived class C++
Equivalent C implementation
6A+ 7 6 KZ " ( "
? 7 6 @KZ ( "
97 76 @KZ " 7 6K}F " ( "
Copyright © 2001 Stephen A. Edwards All rights reserved
// Invoke Shape::translate()
Copyright © 2001 Stephen A. Edwards All rights reserved
Implementing Inheritance
member functions of the Shape class
class Line : public Shape { };
Shape *dlist[10];
6A 97 L 761K}F " ( "
// Hard to add new object
Virtual Functions class Shape { virtual void draw(); }; class Line : public Shape { void draw(); }; class Arc : public Shape { void draw(); }; Shape *dl[10]; dl[0] = new Line; dl[1] = new Arc; dl[0]->draw(); dl[1]->draw();
draw() is a virtual function invoked based on the actual type of the object, not the type of the pointer
New classes can be added without having to change “draw everything” code
// invoke Line::draw() // invoke Arc::draw()
Copyright © 2001 Stephen A. Edwards All rights reserved
4
Implementing Virtual Functions Involves some overhead class Virt { int a, b; virtual void foo(); virtual void bar(); };
(
&Virt::foo &Virt::bar
vptr a b
How the language was first compiled Full compiler that produced C as output C++ semantics therefore expressible in C C++ model of computation ultimately the same C++ syntax substantial extension of C
C++ $
I 7
Virtual table for class Virt
Object of type Virt
Cfront
? - $ /?* I .
Equivalent $ $ C implementation
I 7
I ;9< -9.#"
(
? -
?* I .
-*,- I ;9< I , ,..,- I .@"
Copyright © 2001 Stephen A. Edwards All rights reserved
Default arguments
C++ semantics refer to the same model as C So why use C++? •
Specifications are clearer, easier to write and maintain
Copyright © 2001 Stephen A. Edwards All rights reserved
Declarations may appear anywhere
Another way to simplify function calls
Convenient way to avoid uninitialized variables
Especially useful for constructors
8- $% $ K 7 % =? ,3* . I 7 $ ? $ B- $ 2>.+8/7-/.#" 7 % $A% ?6 % 2 =96 % - .#" +2C>@"
78J- $% C2 $ " 6 % " NN. 0N 2 1 !@" (
void foo(int a, int b = 3, int c = 4) { /* … */ } C++
Expands to
foo(3)
foo(3,3,4)
foo(4,5)
foo(4,5,4)
foo(4,5,6)
foo(4,5,6)
Copyright © 2001 Stephen A. Edwards All rights reserved
Multiple Inheritance Rocket Science Inherit from two or more classes:
Copyright © 2001 Stephen A. Edwards All rights reserved
Multiple Inheritance Ambiguities What happens with duplicate methods? class Window { void draw(); }; class Border { void draw() };
class Window { … };
class BWindow : public Window, public Border { };
class Border { … }; class BWindow : public Window, public Border { … };
BWindow bw; bw.draw();
Copyright © 2001 Stephen A. Edwards All rights reserved
// Error: ambiguous
Copyright © 2001 Stephen A. Edwards All rights reserved
5
Multiple Inheritance Ambiguities
Duplicate Base Classes
Ambiguity can be resolved explicitly
A class may be inherited more than once
class Window { void draw(); };
class Drawable { … };
class Border { void draw() };
class Window : public Drawable { … };
class BWindow : public Window, public Border {
class Border : public Drawable { … };
void draw() { Window::draw(); }
class BWindow : public Window, public Border { … };
};
BWindow gets two copies of the Drawable base class
BWindow bw; bw.draw(); // BWindow::draw() calls Window::draw() Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
Duplicate Base Classes
Implementing Multiple Inheritance
Virtual base classes are inherited at most once
A virtual function expects a pointer to its object struct A { virtual void f(); } struct B { virtual void f(); } struct C : A, B { void f(); }
class Drawable { … }; class Window : public virtual Drawable { … };
E.g., C::f() expects “this” to be a C*
class Border : public virtual Drawable { … };
But this could be called with “this” being a B*
class BWindow : public Window, public Border { … };
BWindow gets one copy of the Drawable base class
Copyright © 2001 Stephen A. Edwards All rights reserved
or
In-memory representation of a C
A B C
Copyright © 2001 Stephen A. Edwards All rights reserved
Implementation Using VT Offsets
Implementation Using Thunks
struct A { int x; virtual void f(); }
struct B { int y; virtual void f(); virtual void g(); } struct C : A, B { int z; void f(); } C c; B *b = &c; b->f(); // C::f()
Create little “helper functions” that adjust
C’s vtbl
C’s vtbl
c
1. b is a B*: vptr has f(), g()
vptr x vptr y z
2. Call C::f( this – 2 ) 3. First argument now points to a C Copyright © 2001 Stephen A. Edwards All rights reserved
Advantage: Only pay extra cost for virtual functions with multiple inheritance
&C::f 0
c
B in C’s vtbl
vptr x vptr y z
&C::f –2 &B::g 0
&C::f B in C’s vtbl
&C::f_in_B &B::g
!"$#&%'( )&* (+,.9 /10 )2 / !3$% )* +3465,87
Copyright © 2001 Stephen A. Edwards All rights reserved
6
Namespaces
Namespaces
Namespace pollution • • • •
Scope for enclosing otherwise global declarations
Occurs when building large systems from pieces Identical globally-visible names clash How many programs have a “print” function? Very difficult to fix
( (
Two f’s are separate
(
'@ 1A
directive brings namespaces or objects into
(
) "
(
/J J 4"= = I6KDI
// Add Mine::g() to Mine
Copyright © 2001 Stephen A. Edwards All rights reserved
Exceptions
Declarations and definitions can be separated
Namespaces
A "
Copyright © 2001 Stephen A. Edwards All rights reserved
4 A 4"== B ?CD6E ."F // invoke Mine::print 4A:1 4 /% 4 G-/ H$D2 I // Mine::pi
) "
# %$'&)(+*,-*/.10 23!.&. "
Namespaces are open: declarations can be added
(
Namespaces
! @ / @
Copyright © 2001 Stephen A. Edwards All rights reserved
scope
/ #7 8 69/: %;$69< 4>== > 4"== ! ?4.1
Copyright © 2001 Stephen A. Edwards All rights reserved
Namespaces
" %$'&)(+*,-*/.10 2-.43/&. # %
Classes suggest a solution
! 65
D
A high-level replacement for C’s setjmp/longjmp
! @ :L; '? /( #7 CD3-+GLC; " /( ?CD +9M ! 7 C> : 4L; D ! )1NC O
Copyright © 2001 Stephen A. Edwards All rights reserved
Copyright © 2001 Stephen A. Edwards All rights reserved
7
Standard Template Library
C++ IO Facilities
I? > A @ 7 %A A )1N O
I/O Facilities: iostream
C’s printing facility is clever but unsafe
Garbage-collected String class
Containers •
vector, list, queue, stack, map, set
Hard for compiler to typecheck argument types against format string
Numerical •
complex, valarray
General algorithms •
C++ IO overloads the << and >> operators
.
@
search, sort
Type safe
Copyright © 2001 Stephen A. Edwards All rights reserved
C++ IO Facilities
Copyright © 2001 Stephen A. Edwards All rights reserved
C++ string class
Printing user-defined types
ostream &operator<<(ostream &o, MyType &m) { o << “An Object of MyType”; return o; }
A
Reference-counted for automatic garbage collection
string s1, s2; s1 = “Hello”; s2 = “There”;
Input overloads the >> operator
s1 += “ goodbye”; s1 = “”; // Frees memory occupied by “Hello goodbye”
int read_integer; cin >> read_integer; Copyright © 2001 Stephen A. Edwards All rights reserved
C++ STL Containers
Vector •
Copyright © 2001 Stephen A. Edwards All rights reserved
Iterators
Mechanism for stepping through containers
Dynamically growing, shrinking array of elements
vector v; vector v; v.push_back(3);
for ( vector::iterator i = v.begin(); // vector can behave as a stack
i != v.end() ; i++ ) {
v.push_back(2); int j = v[0];
int entry = *i; // operator[] defined for vector
}
… v.begin()
Copyright © 2001 Stephen A. Edwards All rights reserved
v.end()
Copyright © 2001 Stephen A. Edwards All rights reserved
8
Other Containers
Associative Containers
Insert/Delete from front mid. end
random access
vector
O(n) O(n) O(1)
O(1)
list
O(1) O(1) O(1)
O(n)
deque
O(1) O(n) O(1)
O(n)
Keys must be totally ordered Implemented with trees set
• Set of objects set > s; s.insert(5); set >::iterator i = s.find(3);
map Associative Array map m; m[3] = “example”;
•
Copyright © 2001 Stephen A. Edwards All rights reserved
C++ in Embedded Systems
Copyright © 2001 Stephen A. Edwards All rights reserved
C++ Features With No Impact
Dangers of using C++ • • •
Classes
No or bad compiler for your particular processor Increased code size Slower program execution
• •
Single inheritance
Much harder language to compile •
•
Unoptimized C++ code often much larger, slower than equivalent C
Copyright © 2001 Stephen A. Edwards All rights reserved
•
Medium-cost Features
Virtual functions
Compiler adds code at call site to set default arguments Long argument lists costly in C and C++ anyway
•
•
•
Function call overhead when an object comes into scope (normal case) Extra code inserted when object comes into scope (inlined case)
• •
•
Often implemented with pointers Extra level of indirection in accessing data Can disappear with inline functions
Inline functions • •
Copyright © 2001 Stephen A. Edwards All rights reserved
Extra level of indirection for each virtual function call Each object contains an extra pointer
References
Constructors and destructors •
Completely resolved at compile time
Copyright © 2001 Stephen A. Edwards All rights reserved
Default arguments •
Completely resolved at compile time
Namespaces •
More compact way to write larger structures
Function name overloading •
Inexpensive C++ Features
Fancy way to describe functions and structs Equivalent to writing object-oriented C code
Can greatly increase code size for large functions Usually speeds execution
Copyright © 2001 Stephen A. Edwards All rights reserved
9
High-cost Features
High-cost Features
Multiple inheritance • • •
Exceptions
Makes objects much larger (multiple virtual pointers) Virtual tables larger, more complicated Calling virtual functions even slower
Templates • • •
Compiler generates separate code for each copy Can greatly increase code sizes No performance penalty
•
•
Uses templates: often generates lots of code Very dynamic data structures have high memorymanagement overhead Easy to inadvertently copy large datastructures
•
When exception is thrown, look up stack until handler is found and destroy automatic objects on the way
•
Mere presence of exceptions does not slow program Often requires extra tables or code to direct clean-up Throwing and exception often very slow
•
Copyright © 2001 Stephen A. Edwards All rights reserved
Bottom-line
Much of the standard template library •
Typical implementation:
•
Copyright © 2001 Stephen A. Edwards All rights reserved
High-cost Features
•
C still generates better code Easy to generate larger C++ executables
Harder to generate slower C++ executables Exceptions most worrisome feature • •
Copyright © 2001 Stephen A. Edwards All rights reserved
Consumes space without you asking GCC compiler has a flag to enable/disable exception support –fexceptions and –fno-exceptions
Copyright © 2001 Stephen A. Edwards All rights reserved
10