C++ Annotations Version 7.3.0

C++ Annotations Version 7.3.0

Frank B. Brokken

Center of Information Technology,
University of Groningen
Nettelbosje 1,
P.O. Box 11044,
9700 CA Groningen
The Netherlands
Published at the University of Groningen
ISBN 90 367 0470 7

1994 - 2009

This document is intended for knowledgeable users of C (or any other language using a C-like grammar, like Perl or Java) who would like to know more about, or make the transition to, C++. This document is the main textbook for Frank's C++ programming courses, which are yearly organized at the University of Groningen. The C++ Annotations do not cover all aspects of C++, though. In particular, C++'s basic grammar, which is, for all practical purposes, equal to C's grammar, is not covered. For this part of the C++ language, the reader should consult other texts, like a book covering the C programming language.

If you want a hard-copy version of the C++ Annotations: printable versions are available in postscript, pdf and other formats in

ftp://ftp.rug.nl/contrib/frank/documents/annotations,
in files having names starting with cplusplus (A4 paper size). Files having names starting with `cplusplusus' are intended for the US legal paper size.

The latest version of the C++ Annotations in html-format can be browsed at:

http://www.icce.rug.nl/documents/

If you want to send in corrections or suggestions, you may want to browse through the suggestions I already received to prevent you from sending in corrections or suggestions I already received. All suggestions and corrections I received since the last version was released can be read at:

http://www.icce.rug.nl/documents/mail

Table of Contents

Chapter 1: Overview of the chapters

Chapter 2: Introduction

2.1: What's new in the C++ Annotations

2.2: C++'s history

2.2.1: History of the C++ Annotations
2.2.2: Compiling a C program using a C++ compiler
2.2.3: Compiling a C++ program
2.2.3.1: C++ under MS-Windows
2.2.3.2: Compiling a C++ source text

2.3: C++: advantages and claims

2.4: What is Object-Oriented Programming?

2.5: Differences between C and C++

2.5.1: Namespaces
2.5.2: End-of-line comment
2.5.3: NULL-pointers vs. 0-pointers
2.5.4: Strict type checking
2.5.5: A new syntax for casts
2.5.5.1: The `static_cast'-operator
2.5.5.2: The `const_cast'-operator
2.5.5.3: The `reinterpret_cast'-operator
2.5.5.4: The `dynamic_cast'-operator
2.5.6: The `void' parameter list
2.5.7: The `#define __cplusplus'
2.5.8: Using standard C functions
2.5.9: Header files for both C and C++
2.5.10: Defining local variables
2.5.11: Function Overloading
2.5.12: Default function arguments
2.5.13: The keyword `typedef'
2.5.14: Functions as part of a struct

Chapter 3: A first impression of C++

3.1: More extensions to C in C++

3.1.1: The scope resolution operator ::
3.1.2: `cout', `cin', and `cerr'
3.1.3: The keyword `const'
3.1.4: References

3.2: Functions as part of structs

3.3: Several new data types

3.3.1: The data type `bool'
3.3.2: The data type `wchar_t'
3.3.3: The data type `size_t'

3.4: Keywords in C++

3.5: Data hiding: public, private and class

3.6: Structs in C vs. structs in C++

3.7: Namespaces

3.7.1: Defining namespaces
3.7.1.1: Declaring entities in namespaces
3.7.1.2: A closed namespace
3.7.2: Referring to entities
3.7.2.1: The `using' directive
3.7.2.2: `Koenig lookup'
3.7.3: The standard namespace
3.7.4: Nesting namespaces and namespace aliasing
3.7.4.1: Defining entities outside of their namespaces

Chapter 4: The `string' data type

4.1: Operations on strings

4.2: Overview of operations on strings

4.2.1: Initializers
4.2.2: Iterators
4.2.3: Operators
4.2.4: Member functions

Chapter 5: The IO-stream Library

5.1: Special header files

5.2: The foundation: the class `ios_base'

5.3: Interfacing `streambuf' objects: the class `ios'

5.3.1: Condition states
5.3.2: Formatting output and input
5.3.2.1: Formatting flags
5.3.2.2: Format modifying member functions

5.4: Output

5.4.1: Basic output: the class `ostream'
5.4.1.1: Writing to `ostream' objects
5.4.1.2: `ostream' positioning
5.4.1.3: `ostream' flushing
5.4.2: Output to files: the class `ofstream'
5.4.2.1: Modes for opening stream objects
5.4.3: Output to memory: the class `ostringstream'

5.5: Input

5.5.1: Basic input: the class `istream'
5.5.1.1: Reading from `istream' objects
5.5.1.2: `istream' positioning
5.5.2: Input from files: the class `ifstream'
5.5.3: Input from memory: the class `istringstream'

5.6: Manipulators

5.7: The `streambuf' class

5.7.1: Protected `streambuf' members
5.7.2: The class `filebuf'

5.8: Advanced topics

5.8.1: Copying streams
5.8.2: Coupling streams
5.8.3: Redirecting streams
5.8.4: Reading AND Writing streams

Chapter 6: Classes

6.1: The constructor

6.1.1: A first application
6.1.2: Constructors: with and without arguments
6.1.2.1: The order of construction

6.2: Const member functions and const objects

6.2.1: Anonymous objects
6.2.1.1: Subtleties with anonymous objects

6.3: The keyword `inline'

6.3.1: Defining members inline
6.3.2: When to use inline functions

6.4: Objects inside objects: composition

6.4.1: Composition and const objects: const member initializers
6.4.2: Composition and reference objects: reference member initializers

6.5: Local classes: classes inside functions

6.6: The keyword `mutable'

6.7: Header file organization

6.7.1: Using namespaces in header files

Chapter 7: Classes and memory allocation

7.1: The operators `new' and `delete'

7.1.1: Allocating arrays
7.1.2: Deleting arrays
7.1.3: Enlarging arrays
7.1.4: The `placement new' operator

7.2: The destructor

7.2.1: Object pointers revisited
7.2.2: The function set_new_handler()

7.3: The assignment operator

7.3.1: Overloading the assignment operator
7.3.1.1: The member 'operator=()'

7.4: The `this' pointer

7.4.1: Preventing self-destruction using `this'
7.4.2: Associativity of operators and this

7.5: The copy constructor: initialization vs. assignment

7.5.1: Similarities between the copy constructor and operator=()
7.5.2: Preventing certain members from being used

7.6: Conclusion

Chapter 8: Exceptions

8.1: Using exceptions: syntax elements

8.2: An example using exceptions

8.2.1: Anachronisms: `setjmp()' and `longjmp()'
8.2.2: Exceptions: the preferred alternative

8.3: Throwing exceptions

8.3.1: The empty `throw' statement

8.4: The try block

8.5: Catching exceptions

8.5.1: The default catcher

8.6: Declaring exception throwers

8.7: Iostreams and exceptions

8.8: Exceptions in constructors and destructors

8.9: Function try blocks

8.10: Standard Exceptions

Chapter 9: More Operator Overloading

9.1: Overloading `operator[]()'

9.2: Overloading the insertion and extraction operators

9.3: Conversion operators

9.4: The keyword `explicit'

9.5: Overloading the increment and decrement operators

9.6: Overloading binary operators

9.7: Overloading `operator new(size_t)'

9.8: Overloading `operator delete(void *)'

9.9: Operators `new[]' and `delete[]'

9.9.1: Overloading `new[]'
9.9.2: Overloading `delete[]'
9.9.2.1: `delete[](void *)'
9.9.2.2: `delete[](void *, size_t)'
9.9.2.3: Alternate forms of overloading operator `delete[]'

9.10: Function Objects

9.10.1: Constructing manipulators
9.10.1.1: Manipulators requiring arguments

9.11: The case of [io]fstream::open()

9.12: Overloadable operators

Chapter 10: Static data and functions

10.1: Static data

10.1.1: Private static data
10.1.2: Public static data
10.1.3: Initializing static const data

10.2: Static member functions

10.2.1: Calling conventions

Chapter 11: Friends

11.1: Friend functions

11.2: Inline friends

Chapter 12: Abstract Containers

12.1: Notations used in this chapter

12.2: The `pair' container

12.3: Sequential Containers

12.3.1: The `vector' container
12.3.2: The `list' container
12.3.3: The `queue' container
12.3.4: The `priority_queue' container
12.3.5: The `deque' container
12.3.6: The `map' container
12.3.7: The `multimap' container
12.3.8: The `set' container
12.3.9: The `multiset' container
12.3.10: The `stack' container
12.3.11: The `hash_map' and other hashing-based containers

12.4: The `complex' container

Chapter 13: Inheritance

13.1: Related types

13.2: The constructor of a derived class

13.3: The destructor of a derived class

13.4: Redefining member functions

13.5: Multiple inheritance

13.6: Public, protected and private derivation

13.6.1: Promoting access rights

13.7: Conversions between base classes and derived classes

13.7.1: Conversions in object assignments
13.7.2: Conversions in pointer assignments

13.8: Using non-default constructors with new[]

Chapter 14: Polymorphism

14.1: Virtual functions

14.2: Virtual destructors

14.3: Pure virtual functions

14.3.1: Implementing pure virtual functions

14.4: Virtual functions in multiple inheritance

14.4.1: Ambiguity in multiple inheritance
14.4.2: Virtual base classes
14.4.3: When virtual derivation is not appropriate

14.5: Run-time type identification

14.5.1: The dynamic_cast operator
14.5.2: The `typeid' operator

14.6: Deriving classes from `streambuf'

14.7: A polymorphic exception class

14.8: How polymorphism is implemented

14.9: Undefined reference to vtable ...

14.10: Virtual constructors

Chapter 15: Classes having pointers to members

15.1: Pointers to members: an example

15.2: Defining pointers to members

15.3: Using pointers to members

15.4: Pointers to static members

15.5: Pointer sizes

Chapter 16: Nested Classes

16.1: Defining nested class members

16.2: Declaring nested classes

16.3: Accessing private members in nested classes

16.4: Nesting enumerations

16.4.1: Empty enumerations

16.5: Revisiting virtual constructors

Chapter 17: The Standard Template Library, generic algorithms

17.1: Predefined function objects

17.1.1: Arithmetic function objects
17.1.2: Relational function objects
17.1.3: Logical function objects
17.1.4: Function adaptors

17.2: Iterators

17.2.1: Insert iterators
17.2.2: Iterators for `istream' objects
17.2.3: Iterators for `istreambuf' objects
17.2.4: Iterators for `ostream' objects
17.2.4.1: Iterators for `ostreambuf' objects

17.3: The class 'auto_ptr'

17.3.1: Defining `auto_ptr' variables
17.3.2: Pointing to a newly allocated object
17.3.3: Pointing to another `auto_ptr'
17.3.4: Creating a plain `auto_ptr'
17.3.5: Operators and members
17.3.6: Constructors and pointer data members

17.4: The Generic Algorithms

17.4.1: accumulate()
17.4.2: adjacent_difference()
17.4.3: adjacent_find()
17.4.4: binary_search()
17.4.5: copy()
17.4.6: copy_backward()
17.4.7: count()
17.4.8: count_if()
17.4.9: equal()
17.4.10: equal_range()
17.4.11: fill()
17.4.12: fill_n()
17.4.13: find()
17.4.14: find_end()
17.4.15: find_first_of()
17.4.16: find_if()
17.4.17: for_each()
17.4.18: generate()
17.4.19: generate_n()
17.4.20: includes()
17.4.21: inner_product()
17.4.22: inplace_merge()
17.4.23: iter_swap()
17.4.24: lexicographical_compare()
17.4.25: lower_bound()
17.4.26: max()
17.4.27: max_element()
17.4.28: merge()
17.4.29: min()
17.4.30: min_element()
17.4.31: mismatch()
17.4.32: next_permutation()
17.4.33: nth_element()
17.4.34: partial_sort()
17.4.35: partial_sort_copy()
17.4.36: partial_sum()
17.4.37: partition()
17.4.38: prev_permutation()
17.4.39: random_shuffle()
17.4.40: remove()
17.4.41: remove_copy()
17.4.42: remove_copy_if()
17.4.43: remove_if()
17.4.44: replace()
17.4.45: replace_copy()
17.4.46: replace_copy_if()
17.4.47: replace_if()
17.4.48: reverse()
17.4.49: reverse_copy()
17.4.50: rotate()
17.4.51: rotate_copy()
17.4.52: search()
17.4.53: search_n()
17.4.54: set_difference()
17.4.55: set_intersection()
17.4.56: set_symmetric_difference()
17.4.57: set_union()
17.4.58: sort()
17.4.59: stable_partition()
17.4.60: stable_sort()
17.4.61: swap()
17.4.62: swap_ranges()
17.4.63: transform()
17.4.64: unique()
17.4.65: unique_copy()
17.4.66: upper_bound()
17.4.67: Heap algorithms
17.4.67.1: The `make_heap()' function
17.4.67.2: The `pop_heap()' function
17.4.67.3: The `push_heap()' function
17.4.67.4: The `sort_heap()' function
17.4.67.5: An example using the heap functions

Chapter 18: Function templates

18.1: Defining function templates

18.2: Argument deduction

18.2.1: Lvalue transformations
18.2.2: Qualification transformations
18.2.3: Transformation to a base class
18.2.4: The template parameter deduction algorithm

18.3: Declaring function templates

18.3.1: Instantiation declarations

18.4: Instantiating function templates

18.5: Using explicit template types

18.6: Overloading function templates

18.7: Specializing templates for deviating types

18.8: The function template selection mechanism

18.9: Compiling template definitions and instantiations

18.10: Summary of the template declaration syntax

Chapter 19: Class templates

19.1: Defining class templates

19.1.1: Default class template parameters
19.1.2: Declaring class templates
19.1.3: Non-type parameters

19.2: Member templates

19.3: Static data members

19.4: Specializing class templates for deviating types

19.5: Partial specializations

19.6: Instantiating class templates

19.7: Processing class templates and instantiations

19.8: Declaring friends

19.8.1: Non-function templates or classes as friends
19.8.2: Templates instantiated for specific types as friends
19.8.3: Unbound templates as friends

19.9: Class template derivation

19.9.1: Deriving ordinary classes from class templates
19.9.2: Deriving class templates from class templates
19.9.3: Deriving class templates from ordinary classes

19.10: Class templates and nesting

19.11: Constructing iterators

19.11.1: Implementing a `RandomAccessIterator'
19.11.2: Implementing a `reverse_iterator'

Chapter 20: Advanced template applications

20.1: Subtleties

20.1.1: The keyword `typename'
20.1.2: Returning types nested under class templates
20.1.3: Type resolution for base class members
20.1.4: ::template, .template and ->template

20.2: Template Meta Programming

20.2.1: Values according to templates
20.2.1.1: Converting integral types to types
20.2.2: Selecting alternatives using templates
20.2.3: Templates: Iterations by Recursion

20.3: Template template parameters

20.3.1: Policy classes - I
20.3.2: Policy classes - II: template template parameters
20.3.2.1: The destructor of Policy classes
20.3.3: Structure by Policy

20.4: Trait classes

20.4.1: Distinguishing class from non-class types

20.5: More conversions to class types

20.5.1: Types to types
20.5.2: An empty type
20.5.3: Type convertability
20.5.3.1: Determining inheritance

20.6: Template TypeList processing

20.6.1: The length of a TypeList
20.6.2: Searching a TypeList
20.6.3: Selecting from a TypeList
20.6.4: Appending to a TypeList
20.6.5: Erasing from a TypeList
20.6.5.1: Erasing duplicates

20.7: Using a TypeList

20.7.1: The Wrap and GenScat templates
20.7.2: The GenScatter template
20.7.3: Support struct and function
20.7.4: Using GenScatter

Chapter 21: Concrete examples of C++

21.1: Distinguishing lvalues from rvalues with operator[]()

21.2: Using file descriptors with `streambuf' classes

21.2.1: Classes for output operations
21.2.2: Classes for input operations
21.2.2.1: Using a one-character buffer
21.2.2.2: Using an n-character buffer
21.2.2.3: Seeking positions in `streambuf' objects
21.2.2.4: Multiple `unget()' calls in `streambuf' objects

21.3: Fixed-sized field extraction from istream objects

21.4: The `fork()' system call

21.4.1: Redirection revisited
21.4.2: The `Daemon' program
21.4.3: The class `Pipe'
21.4.4: The class `ParentSlurp'
21.4.5: Communicating with multiple children
21.4.5.1: The class `Select'
21.4.5.2: The class `Monitor'
21.4.5.3: The class `Child'

21.5: Function objects performing bitwise operations

21.6: Implementing a `reverse_iterator'

21.7: A text to anything converter

21.8: Wrappers for STL algorithms

21.8.1: Local context structs
21.8.2: Member functions called from function objects
21.8.3: The unary argument context sensitive Function Object template
21.8.4: The binary argument context sensitive Function Object template

21.9: Using `bisonc++' and `flex'

21.9.1: Using `flex' to create a scanner
21.9.1.1: The derived class `Scanner'
21.9.1.2: Implementing `Scanner'
21.9.1.3: Using a `Scanner' object
21.9.1.4: Building the program
21.9.2: Using both `bisonc++' and `flex'
21.9.2.1: The `bisonc++' specification file
21.9.2.2: The `flex' specification file
21.9.2.3: Generating code
21.9.3: Using polymorphic semantic values with Bisonc++
21.9.3.1: The parser using a polymorphic semantic value type
21.9.3.2: The scanner using a polymorphic semantic value type