Introduction To C

++

BBRS IP Software Group

© 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

www.marconi.com

References 

The C++ Programming Language (third edition) - Bjarne Stroustrup

BBRS IP Software Group

2

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

References 

ISO/IEC 14882:1998 Standard for the C++ Programming Language My notes from the 1999 Software Development conference:  

http://dcserver/~dcharlap/sd99

BBRS IP Software Group 

Some of my examples are taken from The C++ Programming Language

3

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Introduction To C++
Part 1: A better C than C
BBRS IP Software Group

© 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

www.marconi.com

C Compatibility 

Almost everything that is strict ANSI-C will compile under C++. Pre-ANSI language features may be incompatible. There are many new reserved words, including class, try, catch, template, namespace, public, private, protected, etc. GCC will automatically compile as C++ if the source file extension is .C, .cc, .cpp, .c++, .cp, or .cxx. A character constant is of type char, not int.
© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 



BBRS IP Software Group  

5

New Comment Style 

In addition to C-style comments, C++ allows the use of a double-slash (//) to designate comments. Many C compilers support this, but this is was not part of standard C until the 1999 revision of the ISO standard (ISO/IEC 9899:1999) 

BBRS IP Software Group

6

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Empty Argument Lists  In C. // Unspecified arguments void bar(void). . // Unspecified arguments void bar(void). The keyword void is required to specify no arguments. // No arguments 7 © 2004. // No arguments  In C++.. an empty argument list indicates no arguments. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.).).. a function prototype declared with an empty argument list indicates an unspecified number of arguments.. // Unspecified arguments void foo(.    void foo().   BBRS IP Software Group  void foo(). // No arguments void foo(.. The void keyword in this context is still supported for backward compatibility.

. printf ("Number is: %d\n". int i. } 8 © 2004. Declare them anywhere that makes the code easier to understand. For example:  BBRS IP Software Group void foo() { printf("entering foo\n"). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. i).Declare Variables Anywhere    It is no longer necessary to declare local variables at the top of a block. A local variable's scope begins where it is declared and ends where its block ends. i = rand().

Loop-Local Variables
Variables can even be declared as part of a loop or conditional construct. The variable's scope will end at the end of the construct.  For example:  

BBRS IP Software Group

void foo() { for (int i=0; i<100; i++) { printf("i is now %d\n", i); } // The next line is an error. i is out of scope after the end of // the loop. printf("Final value: %d\n", i); }

9

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Loop-Local Variables 

Note that the scoping of variables declared in a loop or conditional has changed from pre-standard versions of the language. Loop- and conditional-declared variables used to exist until the end of the block containing the construct (as if the variable was declared immediately before the start of the construct.) This is not true anymore! Unfortunately, this discrepancy can result in code that is not portable to pre-standard C++ compilers. If this is a concern, you must declare variables separately from loop and conditional constructs.
© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 

BBRS IP Software Group 

10

Loop-Local Variables 

This used to be legal, but is not anymore: 

void foo() { for (int i=0; i<100; i++) { printf("i is now %d\n", i); } printf("Final value: %d\n", i); }

BBRS IP Software Group 

This is a workaround: 

void foo() { int i; for (i=0; i<100; i++) { printf("i is now %d\n", i); } printf("Final value: %d\n", i); }

11

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

New Enum Functionality   

It is legal for the same name to be declared in two different enumerated types, even with different values. When this is done, the enum's name must be specified at the point of usage, in order to resolve the ambiguity. For example: 

BBRS IP Software Group 

enum lsp_session_type { ip4 = 7, ip6 = 8 }; enum hop_type { ip4 = 1, ip6 = 2 };  

enum lsp_session_type s; enum hop_type h; s = lsp_session_type::ip4; h = hop_type::ip4;

12

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Default Function Arguments 

A function may be defined with default values in the prototype. For example: 

obj *create_obj(int arg1=5, int arg2=10, int arg3=15, int arg4=20); 

When called, any missing parameters are filled in with the defaults. For example, these pairs of calls are all identical: 


BBRS IP Software Group  

object *a, *b; a = create_obj(); b = create_obj(5, a = create_obj(7, b = create_obj(7, a = create_obj(3, b = create_obj(3,

10, 15, 20); 17); 17, 15, 20); 9, 87); 9, 87, 20);

13

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Default Function Arguments 

All arguments with defaults must come after all arguments that do not have defaults: 
 

int f(int, int=0, char* =0); // OK int g(int=0, int=0, char*); // error int h(int=0, int, char* =0); // error

BBRS IP Software Group 

Note that the space after the * in the third argument is significant. Otherwise it will get parsed as the *= operator, which is a syntax error.

14

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Don't do this if you value your sanity! © 2004. // error . }  Declaring the name in a nested scope to hide an outer declaration can lead to all kinds of hard-to-debug errors. // OK. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.changed default void g() { void f(int x=9). but hides outer declaration . void f(int=7).. // error .Default Function Arguments  A default argument can not be repeated or changed in subsequent declarations in the same scope:     BBRS IP Software Group void f(int x=7).. 15 .repeated default void f(int=8).

the inline function definition must appear in every file in which it's used.  BBRS IP Software Group  16 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .Inline Functions  Inline functions are a core language feature. It is therefore customary to declare all inline functions in the same header file with the function prototype. not a compiler-specific extension. For obvious reasons.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. References behave similar to pointers.References  C++ introduces the concept of references. but they are accessed like the objects that they refer to.  BBRS IP Software Group  17 © 2004.meaning reference variables must always be initialized. A reference is denoted by an & character A reference can never be NULL . .

} BBRS IP Software Group   Most people consider the version using references easier to read and understand. 18 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.References  The following two functions are equivalent:  void quadruple(u_int32 *i) { *i = *i * 4. } void quadruple(u_int32 &i) { i = i * 4. It is also more popular among C++ programmers. © 2004.

Some cases where pointers are necessary are:     BBRS IP Software Group When interfacing with C code When a function is returning dynamically-allocated data When support for a NULL object/pointer is required 19 © 2004. .References  In general. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. it is preferable to use references instead of pointers whenever possible.

20 .  When used. ip_addr_t make_ip_address(u_int8 octet1. ip_addr_t make_ip_address(u_int8 octet_list[4]). u_int8 octet2.Function Overloading  The types of the argument list of a C++ function is part of it's name. u_int8 octet3. These prototypes define three different functions:     BBRS IP Software Group ip_addr_t make_ip_address(u_int32 addr). © 2004. the provided argument types will tell the compiler which function to call. u_int8 octet4). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

two functions with the same name but different arguments should perform the same function. Functions can not be overloaded on their return types. . 21 © 2004. ip_addr get_ipaddr(object_t obj). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Function Overloading  In order to avoid confusion. This is illegal:    BBRS IP Software Group u_int32 get_ipaddr(object_t obj).

Function Overloading  Function overloading can make errors in prototypes hard to track down. 22 © 2004.  Instead of:  BBRS IP Software Group smdb_error foo_table::notify_imp( smdb_cdb_iterator::operation op). in SMF. if you accidentally define a persistent table using:  smdb_error foo_table::notify_imp(). . This will probably result in unexpected behavior. You will have defined a different function which will not be called. For instance.  There will be no error. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

the calling convention is changed. } 23 © 2004. . To override this and use C calling conventions. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. C code can not call C++ functions because of this. declare the prototype "extern C" this way:   BBRS IP Software Group extern "C" u_int32 get_addr(object_t *obj).  Or this way:  extern "C" { u_int32 get_addr(object_t *obj).Calling Convention  In order to implement function overloading (and other C++ language features).

Calling Convention  You can also wrap entire headers this way:  extern "C" { #include <sys_inb.  24 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.h> } BBRS IP Software Group  Note that use of extern "C" only changes the calling convention. you can't overload it). but it is still compiled with the C++ language. You can still use all C++ language features in the function's implementation. This places some restrictions on the function (for example. © 2004.

. 25 © 2004.New Memory Allocation  While malloc() and free() still exist. Do not delete what you allocate with malloc(). Instead. BBRS IP Software Group  Note that new and delete are not compatible with malloc() and free(). delete f. use the new and delete operators:    foo_t *f = new foo_t. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. their use in C++ is discouraged. and do not free() what you allocate with new.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.New Memory Allocation  The new and delete operators may also be used to allocate arrays of objects. For example:   foo_t *f = new foo_t[10]. This is a requirement to prevent unwanted side effects involving destructors (to be discussed later.) 26 © 2004. delete[] f.  BBRS IP Software Group Note the syntax change for delete. .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 27 . Where casts are necessary. The rules of assignment compatibility and object inheritance (to be discussed later) make most casts unnecessary. there are four types of casts:      BBRS IP Software Group Dynamic Static Reinterpret Const  Dynamic casts are part of run-time type identification and will be discussed later. casting is discouraged.New Cast Syntax  In C++. © 2004.

28 © 2004. foo *f = static_cast<foo *>(x).  You write:  bar *x. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. use it to cast an integer onto a pointer. (You can't for instance. .) Instead of writing:   BBRS IP Software Group bar *x. It behaves almost identically to a C-style cast. but the types have to be somewhat compatible. foo *f = (foo *)x.Static Cast  The static_cast is similar to a C-style cast.

there is reinterpret_cast.Reinterpret Cast  Sometimes you need to perform a cast that static_cast can't handle. To do this. or you may be interfacing with a library that returns a pointer in an integer variable. unsigned char *video_buffer = reinterpret_cast<unsigned char *>(0xb8000). For example:    BBRS IP Software Group  int pointerValue = 0x12345678. 29 © 2004. which tries to produce a value of the new type with a bit pattern as close as possible to the source type. For example. . you may need to access something at a specific memory location. int *p = reinterpret_cast<int *>(pointerValue). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

const foo *cf = &foo_object. foo *f = const_cast<foo *f>(cf). it does not change the object that is pointed to. © 2004. To do this. If the object is const (and not just the pointer). 30 .  Note that this only changes the pointer type.Const Cast  Sometimes you have a pointer to a const object and you need to get a pointer to a non-const object from it. use const_cast:   BBRS IP Software Group foo foo_object. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. casting away the const attribute may lead to undefined behavior.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. One place where casting is necessary is when casting from a void pointer onto a pointer to an actual type. . most of the situations where casts were required in C have language constructs that will do the same thing more cleanly in C++.  but this will:  int *pi = static_cast<int *>(malloc(10*sizeof(int)). 31 © 2004. This won't compile in C++:   BBRS IP Software Group  int *pi = malloc(10*sizeof(int)).Casting in C++  In general. there is little need for casting in C++.

Where possible.New Casts  If you must cast. Use of the new casts instead of C-style casts also makes it easier to search for casts in code. . It is nearly impossible to write a regular expression to reliably search for C-style cast expressions. using the new casts will allow the compiler to better optimize the expression. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group  32 © 2004. use static_cast or const_cast and avoid reinterpret_cast.

33 © 2004. For example:  BBRS IP Software Group void f(double d) { int i = int(d). the expression T(e) is equivalent to static_cast<T>(e).Constructor Syntax For Casts  Constructing a value of type T from value e can be expressed as T(e). . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. complex z = complex(d). }  For a built-in type T.

types and variables   For the first three. 34 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. the preprocessor is used for many different things. © 2004.Avoid The Preprocessor When Possible  In C. the preprocessor must still be used For the rest. C++ language constructs exist which are easier to understand and are less prone to unexpected side-effects. including:     BBRS IP Software Group   Header inclusion Conditional compilation Inserting code fragments Inserting code blocks Dynamic generation of function code Defining constants.

var |= *ptr++.  Use references if an argument's value must be altered. inline functions may be used instead. . \ (VAR) |= (*(PTR)++). instead of this:  BBRS IP Software Group  #define LOAD_2BYTE(PTR.  For example. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Avoid The Preprocessor When Possible For places where the preprocessor is used to insert code blocks. } typedef unsigned char *puchar.VAR) { \ (VAR) = (*(PTR)++) << 8. inline void LOAD_2BYTE(puchar &ptr. }  Do this:  35 © 2004. u_int32 &var) { var = (*ptr++) << 8.

this:   BBRS IP Software Group #define min(a. . } 36 © 2004. where the argument types are not known in advance.b) (((a)<(b)) ? (a) : (b))  May be rewritten as this:  template<class T> inline T min(T a.Avoid The Preprocessor When Possible  Another common place is when defining function-like macros. For example. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. T b) { return ((a<b) ? a : b). Templates (to be covered later) may be used to provide this functionality.

T b) { return ((a<b) ? a : b). has many advantages aside from not being a macro: BBRS IP Software Group   37 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } The template will make sure that a and b are compatible types (resulting in compiler errors if they are not. .Avoid The Preprocessor When Possible  This version:  template<class T> inline T min(T a.) The problem of macro arguments being evaluated multiple times (resulting in multiple-execution of side-effects) doesn't occur.

use either an enum or a const int. .Avoid The Preprocessor When Possible   For places where the preprocessor is used to define constants. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. BBRS IP Software Group  Use these:   38 © 2004. const u_int32 fill_pattern = 0xdeadbeef. Instead of these:   #define CTYPE_HOP_IP4 (1) #define CTYPE_HOP_IP6 (2) #define FILL_PATTERN (0xdeadbeef) enum ctype_hop { ip4 = 1. ip6 = 2 }.

int c4. int c2 = 2. 39 © 2004. c3 and c4 will because the values are not known at compile time. because p points to it.Avoid The Preprocessor When Possible   The mechanism for declaring const variables is much more optimized in C++. . c1 may not have storage assigned to it. For example:  BBRS IP Software Group const const const extern const const int c1 = 1. If the value of a const variable is known at compile time and is known not to change. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. the compiler does not typically assign storage for that variable. c2 will. int *p = &c2.  In these examples. int c3 = foo(3).

int bar[N]. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  For example.Avoid The Preprocessor When Possible Types that are declared using macros may be declared using the template mechanism (to be covered later). © 2004. this:   BBRS IP Software Group #define MY_STRUCT(N) struct { char *foo. . }. } \ \ \ \ \  May be rewritten as:  40 template <int i> struct mystruct { char *foo. int bar[i].

Mutable    BBRS IP Software Group  Many times. or explicitly cast away const when accessing the field. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 41 © 2004. even when the struct is declared const. Both of these are bad. Not making the struct const will not allow the compiler to catch attempts to write to the struct. These also prevent the compiler from making optimizations that depend on the const-nature of the struct. Explicitly casting away const will not allow the compiler to catch mistakes if the wrong field is accessed. you have to either not declare it const. In C. you have a struct where you always want to be able to write to a specific field.

Mutable  C++ introduces the mutable keyword to work around this. For example:    const foo f = {1. // OK . even when the struct is const.foo. c. .c is mutable f. b. BBRS IP Software Group  A mutable field is always writable. For example:  struct foo { int int mutable int int } a.d = 9. f. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. d.f is still const 42 © 2004. // error . 4}. 2. 3.c = 7.

Introduction to C++ Part 2: New Language Concepts BBRS IP Software Group © 2003. www.com . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.marconi.

www.Introduction to C++ Structs and classes BBRS IP Software Group © 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.com .marconi.

In addition to storing data ("data members") in a struct. . you can also associate functions ("member functions") with a struct.Structs  In C++. A member function is also known as a method. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. A method's name need only be unique within the context of the struct.  BBRS IP Software Group  45 © 2004. the definition of a struct has changed.

 BBRS IP Software Group   46 © 2004.Structs  It is common and often useful for members of different classes to have the same name. or pointer to. . The act of bundling together data and methods designed to act on that data is known as encapsulation. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Methods are called through an instance of. or reference to the struct. Memory allocated to contain a struct's data is often referred to as an object or as an instance of the struct.

set_network_order(u_int32).Structs  Here's an example of a possible IP address struct:  struct ip_addr { u_int32 addr. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group      47 No typedef is required The final semicolon is mandatory! © 2004. // Host order u_int32 u_int32 void void }. host_order(). . set_host_order(u_int32). network_order().

. } BBRS IP Software Group    48 © 2004. } void ip_addr::set_network_order(u_int32 newaddr) { addr = ntohl(newaddr). } void ip_addr::set_host_order(u_int32 newaddr) { addr = newaddr. } u_int32 ip_addr::host_order() { return addr. but with the :: operator to indicate the struct they belong to:  u_int32 ip_addr::network_order() { return htonl(addr).Structs  The methods are defined like ordinary functions. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Structs  Methods are called by dereferencing the struct using the same ". 49 © 2004. printf("b is 0x%x\n".set_network_order(0x78563412).  ip_addr a. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission." and "->" operators that are used for accessing data members. b->set_host_order(0x12345678). ip_addr *b. a. printf("a is 0x%x\n". // Assume this points to something BBRS IP Software Group a. . b->host_order()).host_order()).

50 . }.. u_int32 network_order() { return htonl(addr). } u_int32 host_order() { return addr. © 2004. BBRS IP Software Group  When declared this way.. the methods will be inline when they are used. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } .Structs  Methods may be defined in-line with the struct definition:  struct ip_addr { u_int32 addr.

The memory used is the struct that the method is called from:  ip_addr *a = new ip_addr. printf("0x%x\n". a->host_order()).Structs  Methods can access the data members of their struct without using a pointer to the struct. a->set_host_order(0x10111213). BBRS IP Software Group 51 © 2004. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

} u_int32 ip_addr::host_order() { return this->addr. }  Most of the time. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . there will be no need to explicitly use the this pointer. 52 © 2004. It is always named this. it is available. These two implementations are identical:   BBRS IP Software Group  u_int32 ip_addr::host_order() { return addr.Structs  If a method actually needs a pointer to the struct it's working on.

. } u_int32 host_order() {return addr. even ones defined afterwards in the struct. u_int32 addr.. This is perfectly legal (but a little confusing):  BBRS IP Software Group struct ip_addr { u_int32 network_order() { return htonl(addr).Structs  Note that methods may access all members. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. } 53 © 2004. } .

. } 54 © 2004. . } inline u_int32 ip_addr::network_order() { return htonl(addr). } inline u_int32 ip_addr::host_order() { return addr.. you can declare inline methods after the struct in the header file:  BBRS IP Software Group struct ip_addr { u_int32 network_order().. u_int32 addr. u_int32 host_order().Structs  In order to avoid the confusion of seeing a member used before it is declared in the file. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

For example:  struct foo { int a.Static Data Members  A static data member is shared by all instances of a struct. BBRS IP Software Group }. foo *g = new foo. 3. static int b. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. f->a f->b g->a g->b = = = = 1.    // This is a unique variable // This overwrites f->b 55 © 2004. . 4. 2.  foo *f = new foo.

This means the method may not modify any data members in the struct. © 2004.  56 The compiler can use this in optimizations. . }.Const Methods  A method may be declared const. For example:  BBRS IP Software Group struct ip_addr { u_int32 addr. } . } u_int32 host_order() const { return addr. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. u_int32 network_order() const { return htonl(addr)..

. 57 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }. To prevent that.Data Protection  With the previous example. the data member addr may be accessed without the accessor member functions.. we can declare it private:  BBRS IP Software Group struct ip_addr { private: u_int32 addr. ..

Public members may be accessed by anything.Data Protection  Private members (data and functions) may only be accessed from that struct's methods. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .  BBRS IP Software Group 58 © 2004.

59 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. set_host_order(u_int32 newaddr). u_int32 u_int32 void void }. we can't call the accessors methods from code declared outside the struct:  BBRS IP Software Group struct ip_addr { private: u_int32 addr. host_order(). . network_order(). set_network_order(u_int32 newaddr).Data Protection  This means that with the following struct.

we must declare the accessor methods public:  BBRS IP Software Group struct ip_addr { private: u_int32 addr. network_order(). public: u_int32 u_int32 void void }. . set_host_order(u_int32 newaddr). host_order(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 60 © 2004.Data Protection  To allow access. set_network_order(u_int32 newaddr).

 BBRS IP Software Group 61 © 2004. .) Because of this. A class is a struct. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. This helps to enforce encapsulation (forcing all access to go through accessor methods. where members are private by default instead of public. the keyword class was invented.Data Protection  It is very common to declare data members private.

This is exactly the same as our previous example:   BBRS IP Software Group class ip_addr { u_int32 addr. host_order(). 62 © 2004.Data Protection  There is no difference between a class and a struct other than the default protection. network_order(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. set_network_order(u_int32 newaddr). set_host_order(u_int32 newaddr). public: u_int32 u_int32 void void }. .

but not by methods of unrelated classes.  BBRS IP Software Group 63 © 2004.Data Protection  In addition to public and private. A protected member may be accessed by methods of that class. called protected. and by methods of subclasses. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . there is a third kind of protection.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }. class Matrix { Vector v[4]. . For example.  64 © 2004. }. imagine classes that describe a Vector (an array of floats) and a Matrix (an array of Vectors):   BBRS IP Software Group class Vector { float v[4].Friends  Sometimes. the data protection keywords are insufficient.

v[i] = 0. i<4. } return r. suppose we want to write a function that multiplies a Vector by a Matrix:  Vector multiply(const Matrix &m. i++) { r. for (int j=0. const Vector &v) { Vector r.v[i] += m.v[j]. } BBRS IP Software Group 65 © 2004. j<4.v[j] * v. .Friends  Now.v[i]. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. j++) r. for (int i=0.

We could make the function a method on one of the classes. but that would allow all other code to have access. this multiply function requires direct access to the data members of both the Vector and Matrix classes.  BBRS IP Software Group  66 © 2004. but that would not allow us access to the other class's data.Friends  As we can see. . We could just make those members public. and one function can't be a method of two classes. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Vector&). Matrix&. Matrix&. Vector&). © 2004.  BBRS IP Software Group  class Matrix.Friends  The solution here is to declare the multiply function to be a friend of the two classes as a part of the class definition. . class Matrix { Vector v[4]. friend Vector multiply(const const }. friend Vector multiply(const const }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // Forward declaration class Vector { float v[4].  67 A friend can access private members of the class that has declared it a friend.

© 2004. BBRS IP Software Group  All methods of foo can access all of bar's private members. }. 68 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Friends  You can also declare an entire class to be a friend of another class (not just a function):  class foo. // Definition is unimportant class bar { // Definition is unimportant friend class foo.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .Friends  Although it is sometimes necessary to declare methods and classes as friends.  BBRS IP Software Group 69 © 2004. it usually is not. Go back and think about what changes you can make to your classes that may make the friends unnecessary. If you find yourself having to declare a lot of friends. then you probably have a design error in your program.

public: ip_addr() { addr = 0x12345678. 70 © 2004. }.  BBRS IP Software Group class ip_addr { u_int32 addr. since objects are normally created by code that's not part of the class.Constructors  A method whose name is the same as the class name is a constructor.} .. It is automatically executed when the object is allocated. Constructors have no return type. Constructors should be public. .. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

a->host_order()). .Constructors  Using the previous example:  ip_addr *a = new ip_addr. printf("0x%x\n". The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. BBRS IP Software Group  71 © 2004.  This will print out "0x12345678" The value is assigned by the constructor which automatically executed when the new operator was called.

public: ip_addr() { addr ip_addr(u_int32 newaddr) { addr ip_addr(ip_addr& newaddr) { addr ip_addr(ip_addr* newaddr) { addr }. .Constructors  Constructors may accept arguments and may be overloaded. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } newaddr. } 72 © 2004. } newaddr. BBRS IP Software Group    = = = = 0. } newaddr->addr. For example:  class ip_addr { u_int32 addr.addr.

ip_addr(*b). . ip_addr g = ip_addr(0xfeedface). ip_addr(0x12345678). ip_addr f(e).Constructors  Arguments to constructors are passed as arguments to the new operator:    BBRS IP Software Group  ip_addr ip_addr ip_addr ip_addr *a *b *c *d = = = = new new new new ip_addr. ip_addr(b).  They're also used for creating objects as local variables and temporary variables:    ip_addr e(0xdeadbeef). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 73 © 2004.

aClass *b = new aClass. . } }.Constructors  If a class has a constructor. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. you must use it when allocating objects.  These lines are illegal.  BBRS IP Software Group class aClass { int x. They require a non-existent default constructor:  aClass a. 74 © 2004. public: aClass(int newX) { x = newX.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. this is exactly what you want. i. // initialize with complex(2) 75 © 2004. For some cases. } . For example:  class complex { double f. public: complex(float new_f) { f=new_f.. i=0. .Explicit Constructors  By default. a single-argument constructor also implies a conversion from that type during initialization. } BBRS IP Software Group  complex z = 2.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Explicit Constructors  In other cases. strcpy(s. news). // Error: Makes an empty string // of int('a') characters wide 76 © 2004. this is not at all what you want. . } BBRS IP Software Group  } string s = 'a'. public: string(int n) { s = new char[n+1]. For example:  class string { char *s. } string(char *news) { s = new char[strlen(news)+1].

Explicit Constructors  Declaring a constructor explicit solves this:  class string { char *s. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . } BBRS IP Software Group 77 © 2004. public: explicit string(int n). string(char *news).

it's the same constructor s3(10). // OK .Explicit Constructors  With the explicit keyword on the integer constructor. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // Error . // OK 78 © 2004. // Error .this is an explicit construction s4 = string(10). we get the following results:    BBRS IP Software Group    string string string string string string s1 = 'a'.this constructor is explicit s2 = 10. // OK s5 = "Foo". // OK s6("Bar").

. Its name is the name of the class. prefixed with a tilde (~). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Destructors  A destructor is a method that is automatically executed when an object is deleted. Destructors typically free any dynamically-allocated objects that are associated with the object being freed.  BBRS IP Software Group 79 © 2004.

Constructors and destructors are run for all objects.   BBRS IP Software Group  This will create and destroy a temporary object:  ip_addr a = ip_addr(0xdeadbeef). no matter how they are created or destroyed. Watch out for unanticipated side effects from temporary object instantiation. static.  This does not:  80 © 2004. ip_addr b(0xdeadbeef).Constructors and Destructors  When you use the array-allocate version of new and delete. This includes dynamic (heap) allocation. global or temporary. the constructor and destructor will be called for every element of the array. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

For objects declared globally. even if it is not allocated with the new operator. the constructor will run the first time the object comes into scope. Globallydeclared objects declared in separate source files are not constructed in a deterministic order.  BBRS IP Software Group   81 © 2004. For static objects.Constructors and Destructors  Constructors for all objects will run as soon as the object is allocated. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. this will happen before the first line of main()! Globally-declared objects in a single source file are constructed in the order they appear in the file.

this may not be deterministic. Objects that are freed simultaneously (like local variables that go out of scope) are destroyed in the reverse order of their construction. even if this is due to it going out of scope. For static and global objects. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Constructors and Destructors  Destructors for all objects will run when the object is freed. © 2004.  BBRS IP Software Group   82 . since the order of construction is not entirely deterministic. The time of destruction for global and static objects is not defined.

83 . Destructors run in the opposite order from the constructors. called. Before { Table cc. For example:  void f(int i) aa. } © 2004. dd. constructed and destroyed if (i>0) before dd is constructed. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. bb and dd are constructed { (in that order) whenever f() is Table aa. in the order they are declared. all object constructors will run when the object enters scope. and destructors will run when the object leaves scope.Constructors and Destructors  BBRS IP Software Group When used as local variables. bb and aa will be } destroyed (in that order) Table dd. exiting. If i>0. cc will be Table bb.

Table t3. } // initialization // assignment  t2 and t3 will be clones of t1. © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. You probably really wanted a new object containing the same data. including any internal pointers. Table t2 = t1. a memberwise copy is made (similar to how C structs are assigned to each other. 84 .) This is often not what you want:  BBRS IP Software Group void f() { Table t1. t3 = t2.Constructors and Destructors  When objects are assigned to each other.

Constructors and Destructors  A copy constructor and an overload of the assignment operator can solve this problem:  BBRS IP Software Group struct Table { ..) Implementations may then do what's appropriate for properly copying the object's data. }   The copy constructor is used during initialization. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Table& operator= (const Table&).. 85 . (Operator overloading will be discussed later. The assignment operator overload is used for assignment. Table(const Table&). © 2004.

} 86 © 2004.). don't forget to consider the possibility of self-assignment (e.Constructors and Destructors  When overloading assignment. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. You probably want to make the assignment a no-op when this happens:  BBRS IP Software Group Table& Table::operator=(const Table& t) { if (this != &t) { // do the data copying here } return *this. . a=a.g.

In other words.  BBRS IP Software Group  87 © 2004. . Otherwise. Don't use malloc() and free() unless the object has no methods and will be allocated or freed by C code. Internal housekeeping data for handling virtual methods and related things will not be initialized. Similarly. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. the constructors will not execute. destructors will not execute if memory is freed using free(). don't do this.Constructors and Destructors  If you allocate an object with malloc(). use new and delete.

 BBRS IP Software Group 88 © 2004. here's a struct containing an array of an unknown number of IP addresses. Note that this will use the array-allocation version of the new and delete operators. The array is allocated by the constructor.Address List Example  For an example of constructors and destructors. It is freed by the destructor. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } BBRS IP Software Group . u_int32 *addrs..Address List Example  class addr_list { int count. addrs = new u_int32[newcount]. } 89 © 2004. public: addr_list(int newcount) { count = newcount. . } ~addr_list() { if (addrs != NULL) delete[] addrs.

 BBRS IP Software Group  90 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. no union members may have constructors or destructors. .Unions  A named union is defined as a struct. where every member has the same address. Because the compiler can't know which member is in use at any given time. but no static members. A union may have member functions.

.  BBRS IP Software Group  91 © 2004. For instance. an IP header with options is an ordinary IP header with an extra field. This is known as inheritance. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Subclasses  It is possible to define an object class in terms of differences from another object.

92 © 2004. u_int8 tos. u_int8 ttl. u_int32 source_addr. }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. u_int32 dest_addr. u_int16 checksum. . u_int16 payload_len. u_int16 packet_id.IP Header example  Here's an IP header:  BBRS IP Software Group struct ip_header { u_int8 version. u_int16 fragmentation_info. u_int8 hdr_length. u_int8 l4pid.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . u_int8 options[40].  The subclass ip_header_with_options inherits all of the fields from ip_header.IP Header example  And here's a struct that inherits from it:  BBRS IP Software Group struct ip_header_with_options : public ip_header { u_int8 options_length. ]. 93 © 2004.

This is perfectly legal:   ip_header *hdr = new ip_header_with_options.Subclasses  A pointer to a subclass is assignment compatible with a pointer its parent (or grandparent. however. 94 © 2004.) class. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. This is not legal:   ip_header_with_options *hdr = new ip_header. etc. BBRS IP Software Group  This assignment compatibility is not commutative.

..  95 © 2004. u_int32 get_source_addr() { return source_addr. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission..Methods and Subclasses  Methods (including constructors and destructors) are inherited just like data members:  BBRS IP Software Group struct ip_header { . u_int32 addr = h->get_source_addr(). } } ip_header_with_options *h.

Method Overrides  It is possible for a class and a subclass to define methods with the same name:  struct ip_header { . BBRS IP Software Group void printsomething() { printf("ip_header\n")... } }.. void printsomething() { printf("ip_header_with_options\n"). } }.. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  struct ip_header_with_options : public ip_header { . 96 © 2004.

the one that is called depends on the type of the pointer or reference used:  ip_header_with_options h. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. ip_header *hh = &h. BBRS IP Software Group   97 © 2004. // This prints "ip_header" hh->printsomething(). // This prints "ip_header_with_options" h.printsomething(). .Method Overrides  When a class and a subclass implement the same method.

 BBRS IP Software Group 98 © 2004. . it is more useful to execute the method that corresponds with the class of the data instead of the class of the pointer. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. This can be done by declaring the method virtual. however.Virtual Methods  Most of the time.

. . virtual void printsomething() { printf("ip_header_with_options\n"). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Virtual Methods  This is the previous class hierarchy. } }  struct ip_header_with_options : public ip_header { .. } } 99 © 2004. with virtual methods:  struct ip_header { . BBRS IP Software Group virtual void printsomething() { printf("ip_header\n")...

// This also prints "ip_header_with_options" hh->printsomething(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group  100 © 2004. . with virtual methods:  ip_header_with_options h. ip_header *hh = &h. // This prints "ip_header_with_options" h.printsomething().Virtual Methods  This is the previous example.

because the resulting code is easier to understand. it is a good idea to continue using it. Nevertheless.  BBRS IP Software Group 101 © 2004. The virtual nature of the method is inherited and can not be removed by subclasses. subclasses do not need to continue using the virtual keyword. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Virtual Methods  Once a method is declared virtual. .

 BBRS IP Software Group 102 © 2004. In order to prohibit instantiation of such classes. in order for two related classes to share a common parent. you can declare a virtual method pure virtual. you may have to define a class that will never be instantiated.Pure Virtual Classes  Sometimes. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . by suffixing "=0" to the declaration.

But you don't want any code allocating instances of the superclass (the undifferentiated interface. Because they share common methods. they must share a common superclass. . imagine a class representing an interface.Pure Virtual Classes  For example.numbered and unnumbered. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. You have two subclasses .)  BBRS IP Software Group  103 © 2004.

}. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. BBRS IP Software Group 104 © 2004. public: virtual int get_index() { return index.Pure Virtual Classes  Here's the class definition for the superclass. } virtual u_int32 get_addr() = 0.  class interface { int index. virtual u_int32 get_ifid() = 0. .

Pure Virtual Classes  Here's the subclass for numbered interfaces:  class numbered_interface : public interface { u_int32 addr. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . public: virtual u_int32 get_addr() { return addr. } } BBRS IP Software Group 105 © 2004. } virtual u_int32 get_ifid() { return 0.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Pure Virtual Classes  And here's the subclass for unnumbered interfaces:  class unnumbered_interface: public interface { u_int32 ifid. public: virtual u_int32 get_addr() { return get_router_addr(). } virtual u_int32 get_ifid() { return ifid. } } BBRS IP Software Group 106 © 2004. .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. and the virtual methods can still be called through those pointers. // OK 107 © 2004. For example:      BBRS IP Software Group  interface *i. There is no problem instantiating either subclass. any attempt to instantiate an interface will result in a compile-time error. *k. . *j.pure virtual j = new numbered_interface. They can still be assigned to pointers to interface. i = new interface. // OK k = new unnumbered_interface.Pure Virtual Classes  With this example. // Illegal .

. and you won't be able to instantiate it.Pure Virtual Classes  A pure virtual method is inherited. but if you don't.  BBRS IP Software Group 108 © 2004. just like all other methods. your subclass will also be pure virtual. You don't have to override all pure virtual methods. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Calling the Superclass  Sometimes. you must name the class. a method must call a method of the parent class. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. using the :: operator. BBRS IP Software Group 109 © 2004. To get a parent class version. . Simply calling the method by name will call the local class version.

}. suppose the IP header classes have a "dump" function:  BBRS IP Software Group  struct ip_header { . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. virtual void dump().... virtual void dump().Calling the Superclass  For example. . struct ip_header_with_options : public ip_header { . }. 110 © 2004.

for (int i=0. dest_addr).. i<options_length. printf("options length: %d\n". options[i]). } BBRS IP Software Group  void ip_header_with_options() { ip_header::dump(). printf("header length: %d\n". version).. i. . hdr_length). i++) printf("options[%d]: %d\n". The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. options_length). } 111 © 2004. printf("destination address: 0x%x\n". .Calling the Superclass  void ip_header::dump() { printf("version: %d\n".

Special Case for Constructors  When constructors run. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. So how do you pass parameters to the superclass constructor? The answer is you specify it using the : operator as part of the method's implementation header.  BBRS IP Software Group 112 © 2004. the superclass constructor always executes before the subclass constructor.

ip_header() {}. dest_addr = dst. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission... u_int32 dst) { source_addr = src. here is an ip_header constructor that allows you to initialize the source and destination addresses. } } 113 © 2004.Special Case for Constructors  For example. ip_header(u_int32 src. . and a default constructor:  BBRS IP Software Group struct ip_header { .

.. } 114 © 2004. ip_header_with_options(u_int32 src. we declare its constructor this way:  BBRS IP Software Group struct ip_header_with_options : public ip_header { . dst) {}.Special Case for Constructors  In order for ip_header_with_options to call the nondefault superclass constructor. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. u_int32 dst) : ip_header(src. .

115 . since basic variables can be initialized with "constructor syntax":  BBRS IP Software Group struct ip_header { . u_int32 dst) : source_addr(src). there is little difference between the two. © 2004. ip_header() {}...Special Case for Constructors  It's worth noting that ordinary variables can be intialized using the same technique. For basic non-const types. dest_addr(dst) {} }  The main difference is that this example uses initialization and the previous example uses assignment. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. ip_header(u_int32 src.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. the destructor that is called when the delete operator is used should be based on what the data is. you should always declare your destructor methods virtual:   BBRS IP Software Group virtual void ~ip_header(). . 116 © 2004. and not what the pointer is. Because of this.Virtual Destructors  As you may have figured out by now.

 BBRS IP Software Group  117 © 2004. A static method is not really a method of the class. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . and therefore can't access an object's members without an explicit pointer to the object. When it is called. methods may be declared static.Static Methods  Like data members. it does not have a this pointer. All the usual protection and scoping rules still apply. The difference between a static method and a nonmember function is that a static method's name is associated with a class.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. A method may not be both static and virtual. .  BBRS IP Software Group   118 © 2004. but don't actually act on objects of that class.Static Methods  This may be convenient when building libraries. Static methods may be called using an object pointer or reference (like normal methods.) They may also be called by explicitly naming the class. Especially when declaring functions that are closely related to a class.

let's add a static method to the ip_address class for identifying the class:  BBRS IP Software Group struct ip_addr { . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. ip_addr::print_classname(). a->print_classname().   119 © 2004. ...Static Methods  For example. static void print_classname() { printf("ip_addr\n"). } }  These two invocations are equivalent  ip_addr *a = new ip_addr.

when used in this capacity. bar3 : private foo. bar2 : protected foo. we've always used the public keyword when one class inherits from another class. bar1 : public foo. © 2004. 120 .Inheritance Protection  So far.  This keyword. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. It is also possible to use private or protected in inheritance:      BBRS IP Software Group class class class class foo. is known as an access specifier because it specifies who may access the base class's members.

Public Inheritance  When a derived class (D) inherits from a base class (B) with the public access specifier (the most common way):    All code may convert a D* pointer to a B* pointer without a cast. All code can access public members inherited from B. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Only friends and members of D and friends and members of classes that inherit from D can access protected members inherited from B. BBRS IP Software Group 121 © 2004. .

Protected/Private Inheritance 

When a derived class (D) inherits from a base class (B) with the protected access specifier:  

BBRS IP Software Group

Only friends and members of D and friends and members of classes that inherit from D can convert a D* pointer to a B* pointer without a cast. Only friends and members of D and friends and members of classes that inherit from D can access protected and public members inherited from B. 

When a derived class (D) inherits from a base class (B) with the private access specifier:  

Only friends and members of D can convert a D* pointer to a B* pointer without a cast. Only friends and members of D can access protected and public members inherited from B.

122

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Inheritance Protection 

Use of an access specifier when inheriting is optional. If it is omitted, a default is used: 


A class inherits with a default access specifier of private A struct inherits with a default access specifier of public

BBRS IP Software Group 

Regardless, you should always provide your own access specifier whenever you derive subclasses, because it makes the code easier to understand. And most of the time, the default (private inheritance of classes) is not what you want.

123

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Introduction To C++
Exceptions
BBRS IP Software Group

© 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

www.marconi.com

Exceptions 

It is common for functions to return error codes. In order to be safe, every time such a function is called, you must check the return code for an error. If the caller can't handle the error, it must pass the error to the calling function. This can be awkward. Especially if the code that handles the error is many calls removed from the code that generates the error. 

BBRS IP Software Group  

125

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Exceptions 

Exceptions solve this problem When an exceptional condition (like an error) is detected, the code will generate (aka "raise" or "throw") an exception. The exception will repeatedly pop (unwind) the call stack until an exception handler is found. If no handler is found, the program will abort. 

BBRS IP Software Group  

126

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Exceptions in C 

In C, you can accomplish similar behavior through careful use of the setjmp() and longjmp() functions. In C++, however, this won't work, because longjmp() doesn't call destructors on all the automatic objects that get freed by the popped stack frames. Exceptions will call destructors on automatic objects while the stack unwinds. 

BBRS IP Software Group 

127

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

"abcdef". . global_ri. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // integer // string // object // pointer 128 © 2004. vector(10.The throw Keyword  Exceptions are generated with the throw keyword. Any kind of object may be thrown as an exception. For example:   BBRS IP Software Group    throw throw throw throw 5.15).

} 129 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. To catch an exception. i). wrap the potential exceptiongenerating code in a try block and put the exception handler in a catch block:   BBRS IP Software Group try { do_something(). } catch (int i) { printf("Caught exception %d\n". .The try And catch Keywords  Exceptions are handled using blocks defined by the try and catch keywords.

dx(). v. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.dy()).%d\n". } catch (int i) { printf("Caught int exception %d\n".Catching Exceptions  You may catch many types of exceptions for one try block:  try { do_something(). i). } BBRS IP Software Group 130 © 2004. v. . } catch (vector v) { printf("Caught vector exception %d.

.Catching Exceptions  If the type of the exception thrown doesn't match what you're catching. catch (. The exception will continue to propagate up the call stack. } 131 © 2004.. If you must be able to catch an unknown exception type.) { printf("Caught unknown exception\n")..   BBRS IP Software Group . you can do it by specifying an ellipsis for the catch argument. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission... then you won't catch it.

 BBRS IP Software Group  132 © 2004. you will catch it.Catching Exceptions  Assignment compatibility still applies. This allows you to define a hierarchy of exception classes for catching errors at various levels of granularity. and a subclass (that was derived with a public access specifier) of that class is thrown. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. The standard C++ library defines and uses a hierarchy of many such exceptions. . If your code is written to catch a class.

The standard exceptions are defined as a class hierarchy: exception BBRS IP Software Group logic_error runtime_error domain_error invalid_argument length_error out_of_range bad_alloc bad_cast bad_exception bad_typeid ios_base::failure overflow_error range_error underflow_error 133 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .Standard Exceptions   The standard C++ library makes extensive use of exceptions to indicate errors of various kinds.

You want to handle what you can. // re-throw the exception } 134 © 2004. The throw keyword.. when used without any parameters from within a catch block will do this:  BBRS IP Software Group try { do_something(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Re-throwing Exceptions   Sometimes.) // catch everything { cleanup_some_state(). you can't completely handle an exception. and then let the exception continue propagating up the stack. . } catch (. throw..

marconi. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Introduction To C++ Part 3: Advanced Concepts BBRS IP Software Group © 2003. www.com .

www.Introduction To C++ Operator Overloading BBRS IP Software Group © 2003.marconi.com . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

this can make your code easier to understand. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group  137 © 2004. . making code an unreadable mess.Operator Overloading  All the standard operators may be overloaded just like functions. When used properly. It can also be abused.

Operator Overloading Example  As an example of where operator overloading may be useful. deltay. } } BBRS IP Software Group 138 © 2004. imagine a class for a two-dimensional vector:  class vector { double deltax. } double dx() { return deltax. . } void set_dy(double newdy) { deltay = newdy. double newdy) { deltax=newdx. } double dy() { return deltay. deltay=newdy. public: vector(double newdx. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } void set_dx(double newdx) { deltax = newdx.

dy()).dy() + v2.dx() + v2. vector &v2) { return vector(v1. . }  But this is awkward to use 139 © 2004. We could write a function to do it:   BBRS IP Software Group vector add_vectors(vector &v1.dx(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. suppose we want to add two vectors together. v1.Operator Overloading Example  Now.

} BBRS IP Software Group  Usage is just like any other use of +:  vector v1(1.dx().dy() + v2. dy=8} 140 © 2004. v1. we can override the + operator:  vector operator+(vector &v1.dx() + v2.Operator Overloading Example  Instead. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.0).3). . vector v3(0. vector v2(10.5). // v3 is now {dx=11. v3 = v1 + v2. vector &v2) { return vector(v1.dy()).

.. The previous operator overload is the same as this:  BBRS IP Software Group class vector { .deltay). } } 141 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission..Operator Overloading In A Class  Most (but not all) operator overloads can also be implemented as a method on the class. deltay + v.deltax. vector operator+(vector &v) { return vector(deltax + v.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . with different argument types (just like functions)   BBRS IP Software Group   142 © 2004.Rules of Overloading  Most (but not all) operators may be overloaded New operators may not be defined The number of arguments to an operator may not be changed Precedence rules may not be changed The same operator may be overloaded many times.

>>.Operator Overloading  Some very commonly-overloaded operators include:    BBRS IP Software Group    Assignment (=) Comparison (==. %=. |=. ^. >>=. +=. -=. !=. *. /. ++. %. <<. /=. --) (for numeric classes) Boolean (|. +=) (when applied to sequences) 143 © 2004. >=. . -. <=. &. ^=. >. ||. <) Arithmetic (+. &=. *=. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. <<=. >>) (when applied to iostream classes) Concatenation (+. &&) (for Boolean and bit-field classes) Streaming I/O (<<.

Exercise Restraint When Overloading  PLEASE don't go overboard. think carefully what code using your overload will look like. after learning about operator overloading. use an ordinary function or method call instead. Well thought out operator overloads can make code easy to understand. Many new programmers. © 2004.  BBRS IP Software Group  144 . If the meaning isn't intuitively obvious. the resulting code is impossible to understand. Overloads that are not well thought out can make code very difficult to understand. Before you decide to define an operator overload. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. More often than not. like to use it all over the place.

marconi. www.com .Introduction To C++ Templates BBRS IP Software Group © 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

let's define a class for a doubly-linkedlist node:   BBRS IP Software Group class list_node { list_node *next. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Linked List Example Templates are a mechanism for dynamically generating types and code as-needed. prev->next=node. public: list_node *get_next() { return next. } void insert_before(list_node *node) { node->prev=prev. . } list_node *get_prev() { return prev. node->next=this. } } 146 © 2004. prev=node.  For example. *prev.

. It requires explicit casting and pointer arithmetic. 147 © 2004. both of which can be sources of errors that the compiler can't catch. We usually want to keep a list of some kind of data.Linked List Example  But an empty list node like this is not normally useful. One solution (which is commonly done in the RCI code) is to put a list node into a larger struct and then do some pointer manipulation in order to access the data (outer struct) from a pointer to the list node (inner struct). There are two big problems with this approach:    BBRS IP Software Group  It is difficult to understand the code when reading it later. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

148 © 2004. The pointer can be NULL There are now two objects that must be allocated and freed together. We are still being forced to cast pointers in order to access the data. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Linked List Example  Another solution is to put a (void *) pointer in the list_node class. . The compiler can't protect us against mistakes if we cast incorrectly. but it still has many problems:   BBRS IP Software Group   We must take steps to make sure that the data objects and the list nodes don't get out of sync with each other. This is easier to understand. and have it point to the data.

we must change or create a class variant.Linked List Example  A third solution is to make lots of variant list_node classes that contain the appropriate data. Cleaning up no-longer-used list class variants can be time consuming.  BBRS IP Software Group   This is a lot of maintenance. We (probably) have to declare these classes separately from the places where we're using them. Every time we need to change the data portion of a list. This can be laborintensive and may introduce errors. If we change our implementation. we've got a lot of classes to change. 149 © 2004. . it will be easy to forget which ones we need and which ones we don't need. In a large project. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.especially the cut-and-paste kind that take a long time to clean up. This can introduce errors .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. but still doesn't solve them all. This solves some of the variant-classes problems.   BBRS IP Software Group  The classes still will be declared separately from usage We still have maintenance issues if we change the data of a list. a list of integers should not have any nodes that are used to keep a list of IP instances. the compiler can't protect us from using pointers to the wrong list_node subclass. We also end up introducing an inheritance relationship between different list-node classes where there may not logically be one.Linked List Example  A fourth solution is to make lots of variant list_node classes that are all subclasses of a common list_node class. . If we declare a pointer to list_node for something. 150 © 2004. For instance.

with placeholders for the missing parts that are provided at the location the variables are declared.in the template definition. 151 . The classes that get generated do not have an inheritance relationship between them. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. so unused classes don't clutter up object code and library files. © 2004. so it only must be modified in one place when changes are necessary. Classes are dynamically generated at the point of usage. Common functionality is declared exactly once .Reason For Templates   BBRS IP Software Group   Templates solve all of these problems by letting you declare the class as a template. so you can't blindly mix them together.

list_node<C> *get_next() { return next. } void insert_before(list_node<C> *node) { node->prev=prev. } list_node<C> *get_prev() { return prev.Linked List Template Example  A template version of the doubly-linked-list node might look like this:  template<class C> class list_node { list_node<C> *next. public: C data. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } } BBRS IP Software Group 152 © 2004. . *prev. prev=node. node->next=this. prev->next=node.

you just declare your nodes using the template. For example     list_node<int> list_node<float> list_node<foo> list_node<foo *> // List of integers // List of floats // List of objects // List of object pointers BBRS IP Software Group  These are dynamically-generated types. These types are separate classes that do not have an inheritance relationship among them.Linked List Template Example  Now. but with the type in the brackets substituted for C in the template. to make a list of integers (or floats. © 2004. All are of the form of the list_node template. or objects).  153 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

} }  And then used as:   myarray<int. // 10 integers myarray<foo. For instance. myarray() { size = i. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 1000> b. // 1000 foo objects 154 © 2004. 10> a. int size. a template to declare an unknown-size array of unknown types might be declared as:  BBRS IP Software Group template<class C.Template Parameters  There may be multiple template parameters. . int i> struct myarray { C data[i].

int size. 155 . in order to allow type-compatibility. } }  The private names used are implementation-defined. but are consistent. __some_private_name2__() { size = 1000. __some_private_name1__() { size = 10. } } struct __some_private_name2__ { foo data[1000]. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. int size. © 2004.Template Instantiation  It should be noted that these usages actually declare two types:  BBRS IP Software Group  struct __some_private_name1__ { int data[10].

} BBRS IP Software Group     } myarray<int. 5> myarray<int> myarray<foo> myarray<foo. b. d. c. int i=10> struct myarray { C data[i]. int size. myarray() { size = i.Default Template Parameters  Template parameters can have default values just like function parameters:  template<class C. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // 5 integers // 10 integers // 10 foo objects // 1000 foo objects 156 © 2004. . 1000> a.

. For example. the standard "minimum of two objects" may be implemented as a template function:  BBRS IP Software Group template<class T> inline T min(T a. } 157 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. T b) { return ((a<b) ? a : b).min() Example  Templates may be used to dynamically declare functions as well as types and classes.

if (min(c.. Memory is not wasted in this case because the template function is declared inline. so there's no need to specify it...b)) . // Assume these are initialized if (min(a.  158 . d..min() Example  Usage of the template version of min() is just like the macro version:   int a...d)) . Each usage with different types ends up creating a new function. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. foo c. BBRS IP Software Group  Note that the type T is induced from the arguments. © 2004. b.

.Template Inheritance  Template classes may inherit from other classes (even other template classes). 159 © 2004. . }.. For example:   BBRS IP Software Group   template<class T> class List<T*> : public list_node { ... }. }.. template<class T> class Vec2 : public vector<T> { .. template<class T> class vector { . }. template<class T> class Vec1 : public vector<void*> { .. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission..

.  You don't have to write:   160 Although you could if you wanted to © 2004. }  BBRS IP Software Group I pointed out that the type T is induced from the arguments. T b) { return ((a<b) ? a : b). It is sufficient to write:  int a.Type Induction  In our min example:  template<class T> inline T min(T a. a = min(b. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. c. b. a = min<int>(b.c).c).

it can simply use those parameter types as the template parameter's type. .c). Since the template parameter is used as the type of the function parameters. b. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. a = min(b.  Then the type of the template parameter would be ambiguous and we would have to specify it. double c. 161 © 2004. if the two parameters were different:  BBRS IP Software Group long a.Type Induction   The compiler is able to induce the template parameter value from the function arguments. Of course.

   162 © 2004. } int a[12]. . // returns 12 arraySize(j). arraySize(a). int size> inline int arraySize( T(&)[size]) { return size.Type Induction  As an interesting curiosity. foo j[37]. // returns 37. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. type induction can be used to implement a version of sizeof that returns the number of elements in an array (instead of the number of bytes):  BBRS IP Software Group template <class T.

Entire books have been written describing all of the things that they are capable of.More Information  Templates are a complicated part of C++. A lot of the standard C++ library is based on templates. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . See http://dcserver/~dcharlap/sd99/advanced_cxx_templates. regarding advanced uses of templates. 163 © 2004.html  BBRS IP Software Group  for my lecture notes from the Software Development 1999 conference.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. www.marconi.Introduction To C++ Namespaces BBRS IP Software Group © 2003.com .

For example     BBRS IP Software Group rsvpte_interface_t *rsvpte_mgr_create_intf. constants. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission... In order to prevent these symbols from conflicting with symbols in user code (or other modules of your library)..Reason For Namespaces  When designing libraries. enums. it is typical to prefix symbols with library... This includes functions. etc. classes. ..or module-names. struct INTF *ospf_mgr_create_intf. 165 © 2004. ldp_err_t ldp_mgr_create_intf. you declare a lot of public symbols.

Reason For Namespaces  This can quickly become difficult to maintain. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Especially when your library name and module name are relatively long. Usage can also become annoying. . BBRS IP Software Group 166 © 2004.

. err_t..Namespace Example  Namespaces solve this... The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. interface_t *mgr_create_intf(.. } namespace rsvpte { typedef .... For example:  BBRS IP Software Group   namespace ospf { struct INTF *mgr_create_intf(.). } namespace ldp { typedef . The symbols can be short and descriptive this way. ..). You declare a namespace and put your symbols in it.). interface_t.. err_t mgr_create_intf(. } 167 © 2004.

). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.... 168 © 2004. rsvpte::interface_t *i..). ldp::err_t e = ldp::mgr_create_intf(.. use the :: operator:    struct INTF *i = ospf::mgr_create_intf(. ..Namespace Example  To resolve a symbol in a namespace.). this doesn't look any better than simply sticking prefixes on the names. i = rsvpte::mgr_create_intf(. So additional features were defined to manage namespaces. BBRS IP Software Group  Of course.

This means that if a name is previously declared in the namespace or an enclosing scope.. return i. The usual scope rules apply to namespaces. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.) { interface_t *i = new interface_t.. . . For instance:   BBRS IP Software Group rsvpte::interface_t *rsvpte::mgr_create_intf(.. you don't need to explicitly name the namespace.. } 169 © 2004.Namespaces  A namespace is a scope.

But what if you frequently need symbols from another namespace? You can. you can use a using-declaration to alias a single symbol into the current scope:  void foo() { using rsvpte::interface_t.. of course. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. fully qualify the symbols but that can quickly become tedious and hard to read.using Declarations    BBRS IP Software Group This works fine for simple cases. interface_t *i. // error! } 170 © 2004.). Instead. where a function sticks with symbols from its own namespace. . i = mgr_create_intf(..

interface_t *i.using Directives  You can also alias an entire namespace into the current scope using a using-directive:  void foo() { using namespace rsvpte... i = mgr_create_intf(.). . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } // OK BBRS IP Software Group 171 © 2004.

.  BBRS IP Software Group  172 © 2004. since it won't have global impact on how code compiles. This should only be used as a transitional tool. A using-directive inside a function can be safely used as a notational convenience.using Directives  A using-directive at the global level effectively deletes the namespace. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. A using-directive inside a namespace definition can be used to create namespaces that are composites of other namespaces. while porting code over to a namespace.

Without naming the namespace. its symbols can only be accessed from functions declared and defined within that namespace. © 2004.Anonymous Namespaces  You can also declare an anonymous namespace. 173 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. For example:  BBRS IP Software Group namespace { int a. void f() { /* do something */ } int g() { /* do something else */ } }  Obviously. there must be a way to call f and g if this is going to be useful.

Anonymous Namespaces    BBRS IP Software Group  In order to make anonymous namespaces useful. In other words.  174 . it will be a different namespace. In the previous example. If the same anonymous namespace appears in a different translation unit. © 2004. f and g can be called from any code in the same translation unit as the namespace's definition. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. It should be obvious that anonymous namespaces in headers are pointless and will lead to much confusion. every one has an implied using-directive at the end of it. anonymous namespaces can make functions private in the same fashion that the static keyword does in C.

if a function isn't found in the context where it is used. This saves a lot of typing. compared to explicit qualification. the compiler will look in the namespaces of its arguments. Note that the namespace and the function must still be declared and in-scope for this to work.Namespaces  A function taking an argument of type T is usually defined in the same namespace as T. but doesn't pollute the namespace the way a using-directive can. .  BBRS IP Software Group  175 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Because of this.

using long.   176 © 2004. But long names are a pain to type in all the time. } namespace rsvp = RCI_RSVP_TE_version_2. To resolve this problem. For instance:  BBRS IP Software Group namespace RCI_RSVP_TE_version_2 { struct interface_t. rsvp::interface_t *i. .Namespace Aliases    In order to avoid conflicts. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. descriptive namespace names is a good idea. namespace aliases can be declared.

namespace rsvpte_parser. } namespace rsvpte_parser { .  177 © 2004. . } namespace { using using using } rsvpte namespace rsvpte_mgr. } namespace rsvpte_state_machine { . namespace rsvpte_state_machine..... For instance.Derived Namespaces  You can derive namespaces from other namespaces.. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. we might declare each sub-module of RSVP in a separate namespace and then compose an overall RSVP namespace from the set of them:   BBRS IP Software Group  namespace rsvpte_mgr { .

Namespace Selection  If you start combining namespaces with using-directives. you can wind up with name conflicts. you can use a using-declaration in the combined namespace.  BBRS IP Software Group   178 . This is known as namespace selection © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Instead. of course resolve these by specifying the namespace when the conflicting names are used. You can. This will resolve the conflict by letting you specify which namespace to take the conflicting symbol from. but this is ugly.

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. for concatenation:  BBRS IP Software Group namespace Library_string { class String { ..Namespace Selection Example  For an example of selection. imagine a private String class (String is a standard library class) defined in a namespace. String operator+(const const String operator+(const const } String&. }. 179 © 2004. This namespace also contains two overrides for the plus operator. String&). String&. char *)..

If I include the standard library's String class header at the same time. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }  Note that this pulls all the overloads of operator+ into the namespace. 180 . it will be ambiguous which class I end up using when declaring variables of type String. and use that:   BBRS IP Software Group namespace My_string { using Library_string::String. I can. using Library_string::operator+.Namespace Selection Example  This can get really messy. © 2004. however. declare my own namespace that selects the symbols I need from Library_string. They are all the same symbol.

deletion of those symbols would result in code silently using the public String class instead.  BBRS IP Software Group  181 . © 2004. Similarly. any new methods on Library_string::String will be automatically pulled into the My_String namespace. If we didn't do this. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Which is probably not what we want.Namespace Selection Example  Using selection like this. but instead used a using-directive to pull Library_string's symbols into scope. code using the My_String namespace will be alerted (through compiler errors) if one of the Library_string symbols should get deleted. Ditto for any new overloads of Library_string::operator+.

182 . to make code easier to understand. } namespace A { int g(). the namespace A contains both f and g.Namespaces Are Open  Finally. You can add symbols to a single namespace from many locations. © 2004. For instance:  namespace A { int f(). This allows us to distribute a namespace's definition across multiple header files. it should be noted that namespaces are open. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } BBRS IP Software Group    At this point.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } 183 © 2004.. you should explicitly state the namespace to prevent errors.Common Namespace Problem  When defining a function that's declared in a namespace.. . with this namespace:  BBRS IP Software Group namespace Mine { void f(). For example. }  This typo will produce an error:  void Mine::ff() { .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. The compiler won't have any way of knowing that the function name is actually a typo.Common Namespace Problem  Had you instead written the function this way:  BBRS IP Software Group namespace Mine { void ff() { .. . 184 © 2004.. } }  Then you would have accidentally defined a new symbol Mine::ff.

More Information  See http://dcserver/~dcharlap/sd99/namespaces_and_their_impact_ on_cxx. regarding namespaces. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.html for my lecture notes from the Software Development 1999 conference. BBRS IP Software Group 185 © 2004. .

marconi.Introduction To C++ Multiple Inheritance BBRS IP Software Group © 2003.com . www. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Multiple Inheritance  When defining a hierarchy of classes. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group 187 © 2004. sometimes a subclass logically should inherit from two or more base classes. . C++ allows this multiple inheritance using standard language features.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } 188 © 2004. We can then define a class to represent a simulated object that both performs activity and I/O:  BBRS IP Software Group class Satellite : public Task. and I/O is performed by a class Displayed. consider a simulation environment where activity is represented by a class Task. public Displayed { ..Satellite Example  For example.. .

transmit().draw(). // Satellite::transmit() } 189 © 2004. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // Displayed::draw() s.Satellite Example  The subclass inherits all data members and methods from both superclasses. // Task::delay() s. in addition to anything it defines locally.delay(10). For example:  BBRS IP Software Group void f(Satellite &s) { s.

// gets a pointer to the Task part } BBRS IP Software Group  190 © 2004. it can be passed to functions that expect either class:  void hilight(Displayed *). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // gets a pointer to the Displayed part suspend(p). void suspend(Task *). .Satellite Example  Similarly. void g(Satellite *p) { hilight(p). because Satellite inherits from both Task and Displayed.

BBRS IP Software Group 191 © 2004.Satellite Example  Virtual functions work as usual. . A function calling a virtual method of a Task or Display pointer will still call the override if passed a pointer to the Task or Display part of a Satellite. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

virtual debug_info *get_debug().. virtual debug_info *get_debug().. .. }. however.Resolving Ambiguity  There is room for ambiguity. Two base classes may have member functions with the same name.  192 © 2004. class Displayed { .. }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. For example:  BBRS IP Software Group class Task { .

Resolving Ambiguity  When the ambiguous method is called. . the specific superclass used must be resolved:  void f(Satellite *sp) { debug_info *dip. // error . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // OK dip = sp->Displayed::get_debug(). dip = sp->get_debug(). // OK } 193 © 2004.ambiguous BBRS IP Software Group dip = sp->Task::get_debug().

*dip2. *dip3. For instance:  BBRS IP Software Group debug_info *Satellite::get_debug() { debug_info *dip1. It is often better to merge the functionality using an override of the ambiguous function. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Displayed::get_debug(). dip1 = dip2 = dip3 = return } Task::get_debug(). dip3. dip1->merge(dip2). . however.Resolving Ambiguity  Explicit resolution of the ambiguity is ugly. 194 © 2004.

// finds Displayed::Draw Displayed::draw(). Satellite::Displayed::draw(). void draw () { draw()... // recursive Satellite::draw(). For instance:  BBRS IP Software Group  class Telstar : public Satellite { . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Resolving Ambiguity By localizing the ambiguous resolution into a single function. // redundant } }. 195 © 2004. . it means subclasses of the multiply-inherited class don't have to worry about the ambiguity.  Subclasses can use whatever qualification they need to resolve calls.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Introduction To C++ Virtual Base Classes BBRS IP Software Group © 2003.marconi.com . www.

we might define a class (Storable) for any object that can write/read itself to/from a file:   BBRS IP Software Group class Storable { public: virtual const char *get_file() = 0. . } }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 197 © 2004. virtual void write() = 0.Common Base Class Example  Sometimes. your class may inherit from two classes that in turn inherit from a common base class. For example. virtual void read() = 0. virtual ~Storable() { write().

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }.. class Receiver : public Storable { public: virtual void write().. }. 198 © 2004.Common Base Class Example  It is logical that all classes that want to be able to store themselves to disk would inherit from Storable:  BBRS IP Software Group  class Transmitter : public Storable { public: virtual void write(). . . ..

public Receiver { public: virtual const char *get_file(). © 2004. let's define a Radio class that consists of both a Transmitter and a Receiver:  BBRS IP Software Group class Radio : public Transmitter. .. virtual void write().Common Base Class Example  Now. 199 .  Note that Radio has two Storable superclasses! One inherited from Transmitter and the other from Receiver. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.. }. virtual void read().

Common Base Class Example  Typically. }  This happens to work OK because the Storable class can be safely replicated. 200 . It contains no data and its write() method is pure virtual. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // radio-specific writing calls.. Receiver::write(). an implementation would call the superclass methods and then call its own private implementation:  BBRS IP Software Group void Radio::write() { Transmitter::write(). © 2004..

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. public: Storable(const char *s). BBRS IP Software Group  This is a problem! There are now two instances of the data in a Radio. Which one gets used? This ambiguity will lead to unpredictable behavior. Storable& operator= (const Storable&). }.Problem With Common Base Classes  But what happens if Storable declares data?  class Storable { const char *store. 201 . .. © 2004. Storable (const Storable&).

. We do this by making the immediate subclasses of Storable virtually inherit from it:   BBRS IP Software Group  class Transmitter : public virtual Storable { . class Receiver : public virtual Storable { . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 202 © 2004... .Reason For Virtual Base Classes  What we need to do is to make sure that there is only one Storable component in a Radio.. }. }.

Virtual Base Classes  All classes that virtually inherit from the same base class will share the same instance of that base class if they are later combined using multiple inheritance. A class that does not virtually inherit from its base class will always get a unique copy of that base class if it is combined with a sibling class using multiple inheritance. .  BBRS IP Software Group 203 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

For example. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Especially if the calls have side effects.Problem With Virtual Base Class Example  Note that in implementations. .a window with a border Window_with_menu .a plain window Window_with_border . This is often incorrect behavior.a window with a menu bar 204 © 2004. you may have issues with the base class's methods being called multiple times for a single instance of a subclass. some classes for windows:     BBRS IP Software Group  Window .

class Window_with_menu : public virtual Window { public: virtual void draw(). . }. }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. class Window_with_border : public virtual Window { public: virtual void draw(). // Draw the window }. class Window { public: virtual void draw(). these might be defined:  BBRS IP Software Group   205 © 2004.Problem With Virtual Base Class Example  Following the Radio example.

// draw a menu bar }  206 © 2004.Problem With Virtual Base Class Example  The implementations for the subclasses can call the superclasses:  BBRS IP Software Group void Window_with_border::draw() { Window::draw(). . // draw a border } void Window_with_menu::draw() { Window::draw(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 207 © 2004.Problem With Virtual Base Class Example  Now let's say that we are defining an application window that has both a border and a menu bar:  BBRS IP Software Group class Clock : public Window_with_border. . public Window_with_menu { public: virtual void draw(). }.

// draw clock stuff }  Notice that Window::draw is called twice! This will waste CPU time and may result in more serious problems. depending on its side effects. 208 . Window_with_menu::draw().Problem With Virtual Base Class Example  But look at what happens if we do a simple implementation of the draw method:  BBRS IP Software Group void Clock::draw() { Window_with_border::draw(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. © 2004.

we can explicitly call the base-class's draw method followed by the non-virtual draw_self methods that we need to call without worrying about the calls propagating to the base class.  BBRS IP Software Group  209 . © 2004.Avoiding Duplicate Base-Class Method Calls  The C++ language doesn't provide a solution for this. Then in the application class. but the problem can be avoided through some clever organization of the classes. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. To do this. we declare separate non-virtual draw_self methods in all of the subclasses and have the draw methods call these.

Avoiding Duplicate Base-Class Method Calls  class Window_with_border : public virtual Window { public: virtual void draw(). class Window_with_menu : public virtual Window { public: virtual void draw(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }. . }. void draw_self(). BBRS IP Software Group  210 © 2004. void draw_self().

} void Window_with_menu::draw() { Window::draw() draw_self(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. } BBRS IP Software Group  211 © 2004.Avoiding Duplicate Base-Class Method Calls  void Window_with_border::draw() { Window::draw(). . draw_self().

Window_with_menu::draw_self(). // draw clock stuff }  This can still cause some maintenance problems. © 2004.Avoiding Duplicate Base-Class Method Calls  Now our application's draw method can be written in a way that doesn't call Window::draw() more than once:  BBRS IP Software Group void Clock::draw() { Window::draw(). 212 . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. but it solves the run-time problem. Window_with_border::draw_self().

For more information. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Multiple Inheritance  There is a lot more to multiple inheritance than just this. see section 15 of The C++ Programming Language  BBRS IP Software Group 213 © 2004.

Introduction To C++ Run-Time Type Identification (RTTI) BBRS IP Software Group © 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.com .marconi. www.

a* aPtr = &bObj. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // Perfectly legal b* bPtr1 = aPtr. // Illegal BBRS IP Software Group     215 © 2004. but not the other way around:  class a. a aObj. b bObj. // Illegal b* bPtr2 = &aObj.The Problem Solved By RTTI   Subclasses are only assignment compatible in one direction. . You can assign a subclass pointer/reference to a base class pointer/reference. class b : public a.

216 © 2004. a* aPtr = &bObj. a aObj. // This shouldn't have worked!  Casting also won't recompute pointer values. b* bPtr1 = (b*)aPtr. // This works b* bPtr2 = (b*)&aObj. which is necessary when doing this with multiple inheritance.The Problem Solved By RTTI  One solution is to simply apply a cast. but with some serious problems if it's not applied correctly:   BBRS IP Software Group    class a. b bObj. class b : public a. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

b* bPtr2 = dynamic_cast<b*>(&aObj). © 2004. class b : public a. bPtr1 will have the correct pointer value. b bObj.  After executing this. bPtr2 will have NULL. 217 . a* aPtr = &bObj. a aObj. It examines the actual type of the data and will do the right thing:   BBRS IP Software Group    class a. since object aObj is incompatible with object class b. b* bPtr1 = dynamic_cast<b*>(aPtr).Dynamic Cast  The solution is the dynamic_cast operator. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

When there are multiple ambiguous base classes (such as when using some extreme cases of multiple inheritance) it will also return NULL. Objects of non-polymorphic classes don't necessarily have the internal pointers to RTTI data that dynamic_cast requires in order to work. The base class in a dynamic_cast must be polymorphic. That is. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group  218 . © 2004.Dynamic Cast  dynamic_cast will return NULL whenever the object and class are not compatible with each other. it must have at least one virtual method.

b bObj. a aObj. dynamic_cast will throw a bad_cast exception when the cast can not be performed. a& aRef = bObj.Dynamic Cast  dynamic_cast works on references as well as pointers. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. © 2004.  In this case. class b : public a. b& bRef1 = dynamic_cast<b&>(aRef). b& bRef2 = dynamic_cast<b&>(aObj). But because there is no such thing as a NULL reference.  BBRS IP Software Group     class a. the last line throws a bad_cast exception. 219 .

class b : public a.Dynamic Cast  When using dynamic_cast with references. } 220 © 2004. try { b& bRef = dynamic_cast<b&>(aObj). } catch(bad_cast) { // The cast failed. Do something about it. it is a very good idea to use an exception handler. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.    BBRS IP Software Group class a. . a aObj.

static_cast can not cast from a virtual base class in multiple inheritance. .) BBRS IP Software Group  221 © 2004. however. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Static vs. Dynamic Cast  static_cast does not check an object's RTTI data to see if the cast is possible. since this is impossible without referencing the RTTI class data that dynamic_cast uses (and static_cast does not use. but it does do the pointer arithmetic needed for casting from one of several base classes in a multiple inheritance hierarchy (unlike a C-style cast).

Static vs. Dynamic Cast  So why should anybody ever use static_cast?  The pointer/reference may be to data that isn't polymorphic (like. from legacy C code) The data may be a (void *) .  BBRS IP Software Group  222 © 2004. . dynamic_cast has some overhead. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. although it's not much.which by definition can not be assumed to point to anything specific and therefore has no accessible RTTI information.

a pointer. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. a reference. For that. an object. or any other expression. But sometimes you need more specific information about a class. typeid returns a reference to a type_info structure (defined in the <typeinfo> header) that identifies the type. typeid may be applied to a type.The typeid Operator  dynamic_cast is usually useful enough for the situations where RTTI is required. Like the sizeof operator. © 2004. there is the typeid operator.  BBRS IP Software Group  223 .

.The typeid Operator  For an example of typeid in action:  #include <typeinfo> void f(Shape &r. BBRS IP Software Group ts = typeid(Shape). // Type of the pointer itself } 224 © 2004. // Info about Shape tr = typeid(r). &tr. // Type of the reference tpp = typeid(*p). // Type of the data pointed to tp = typeid(p). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Shape *p) { type_info &ts. &tpp. &tp.

BBRS IP Software Group 225 © 2004. type_info& operator=(const type_info&). bool before(const type_info&) const. bool operator!=(const type_info&) const.The type_info Class  The portable parts of the type_info class look like:  class type_info { public: virtual ~type_info(). const char *name() const. . }. bool operator==(const type_info&) const. private: type_info(const type_info&). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

It is important to use these on the type_info objects and not simply comparing the values of pointers to type_info objects.The type_info Class   BBRS IP Software Group    The destructor (~type_info) is to ensure that the class is polymorphic. The before() method is used for ordering the types (for sorting. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. because there may be several type_info objects corresponding to a single type. 226 .it only has to be consistent within a single run of the program. The == and != operators are used to test equality. The name() method retrieves the type's name The private copy constructors prevent accidental duplication of type_info objects.) The order is arbitrary . © 2004.

There are. .Avoid Abuse of RTTI  Most of the time. inheritance. some legitimate situations where RTTI may be needed. Virtual methods.  BBRS IP Software Group  227 © 2004. and templates provide most of the application-level features that many programmers try to gain through use of RTTI. however. there will be no need for any RTTI (dynamic_cast or typeid). so don't design an overly complicated solution simply to avoid using it. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

More Information  See http://dcserver/~dcharlap/sd99/rtti. regarding run-time type indentification. . BBRS IP Software Group 228 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.html for my lecture notes from the Software Development 1999 conference.

www.marconi.com .Introduction to C++ Part 4: The Standard C++ Library BBRS IP Software Group © 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

. You can simply include the same headers as before:   #include <stdio.h> printf("foobar\n").C-Compatible Library Components  All of the features of the C library are available in C++. BBRS IP Software Group 230 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

h suffix. .C-Compatible Library Components  A preferable way. The header names are the same as before. 231 © 2004. The symbols declared in the new headers are all in the std namespace. For example:   BBRS IP Software Group  #include <cstdio> std::printf("foobar\n"). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. in order to avoid collision with user code. is to use the new headers for these components. however. but with a c prefix and without the .

232 © 2004. although some pre-standard compilers may not yet have put them where they belong. For instance:  #include <iostream> #include <vector> #include <stack> BBRS IP Software Group  All standard library symbols are in the std namespace. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .New Headers  Most of the new headers do not have any suffix on their filenames.

 BBRS IP Software Group   233 . they may be used in place of the standard C library's printf/scanf functions. respectively. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. and cerr (actually std::cin. and stderr. In the simplest form. © 2004.I/O Streams  #include <iostream> I/O streams are a mechanism for objects to write their data out to text and binary streams. The standard streams cin. and to read their data back from those streams. cout. std::cout and std::cerr) allow access to the standard I/O handles stdin. stdout.

y. z).  is equivalent to:  BBRS IP Software Group int x. y is %d. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.I/O Streams  For an output example:  int x. z. Assume they're there. printf("x is %d. y.  (I won't be pedantically mentioning the std:: namespace in the rest of my examples. y. x. z is %d\n". 234 . std::cout << "x is " << x << " y is " << y << " z is " << z << '\n'. z.) © 2004.

&y. &z. y. cin >> y. cin >> z. cin. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. scanf("%d %d %d %10s". z. char buffer[10]. y.  is equivalent to  BBRS IP Software Group int x. char buffer[10]. 235 © 2004.width(10).I/O Streams  And for an input example:  int x. buffer). z. . &x. cin >> x. cin >> buffer.

const jpeg &j).  236 © 2004. For example.. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. one possible way to import and export JPEG image files might be:   BBRS IP Software Group class jpeg { . jpeg &j).I/O Streams  More complicated data can be read and written by overloading the << and >> operators. ostream& operator<<(ostream &s.. cout << j. jpeg j. cin >> j. istream& operator>>(istream &s. . }.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.) Streams that read and write strings can be created using the istringstream and ostringstream classes (in the <sstream> header. . Streams that read and write files can be created using the ifstream and ofstream classes (in the <fstream> header.)  BBRS IP Software Group  237 © 2004.I/O Streams  Formatting of stream input and output can be performed by calling various methods on stream objects.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.marconi. www.com .Introduction to C++ Containers BBRS IP Software Group © 2003.

bitset. . array) 239 © 2004. multiset) "Almost" containers (string. set. list. valarray. optimized for different access patterns:   BBRS IP Software Group   Sequences (vector. multimap.Containers  Containers are object classes that are used to store other objects. queue. deque) Sequence adaptors (stack. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. priority queue) Associative types (map. There are different kinds of containers that store the objects in different ways.

you specify the type of object you want it to contain. When instantiating a container. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .Containers  All containers are template classes. For example:   BBRS IP Software Group  vector<int> // A vector of integers list<float> // A list of floats deque<IpAddr> // A deque of IP addresses 240 © 2004.

.Iterators  All sequence-containers use iterators for traversal. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. There are several kinds of iterators:     BBRS IP Software Group  Output (Out) Input (In) Forward (For) Bi-directional (Bi) Random-Access (Ran) 241 © 2004.

.Iterators  Different kinds of iterators support different subsets of the following operations:     BBRS IP Software Group  Read Access Write Iteration Comparison 242 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.+ . Note that not all operators are applicable to all kinds of iterators: Input Output Forward = *p -> Bi-directional = *p -> *p = ++ -== != Random = *p -> [] *p = ++ -.+= -= == != < > <= >= BBRS IP Software Group Read Access Write Iteration Compare = *p -> *p = ++ == != ++ *p = ++ == != 243 © 2004.Iterators  Iterator operations are performed via overloaded operators.

containers.Iterators  There is a lot more to say about iterators.) See chapter 19 of The C++ Programming Language for all the details. strings. . since most of their use is in the context of the objects they iterate over (e. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. but we won't discuss them here.  BBRS IP Software Group 244 © 2004. etc.g.

 BBRS IP Software Group 245 © 2004. . Other standard containers support most of vector's functionality. Unless otherwise noted. all containers share vector's interface. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Some containers add additional functionality.Vector  A vector is the most basic kind of container.

) List operations (insert. delete. It has the following features:      BBRS IP Software Group Iterators for traversing the list. etc. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. The subscript operator may be used for random access Stack operations (push.Vector  Defined in the <vector> header A vector is effectively a dynamically-resizing array.) 246 © 2004. etc. . pop.

const_pointer . const_iterator .for backward traversal pointer.reference to an element 247 © 2004.pointer to an element reference.the type of the memory manager object size_type .the type used for indexing elements difference_type . const_reverse_iterator .the type resulting from subtracting two iterators iterator. .for forward traversal reverse_iterator.the type of each element allocator_type . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Vector Types  Vector defines the following typedefs as a part of the template:     BBRS IP Software Group     value_type . const_reference .

} 248 © 2004.end()) { s += *p. typename C::const_iterator p = c.  For example. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. a template function to add up all the elements in a container:   BBRS IP Software Group template<class C> typename C::value_type sum(const C& c) { typename C::value_type s = 0. // increment an iterator to go to the next object } return s. while (p != c. // dereference an iterator to get the object ++p.begin(). .Vector Types These types allow member function to access the container without knowing anything about the actual objects.

   249 The begin() functions point to the first element in the (forward or reverse) sequence. const_reverse_iterator rbegin() const.Vector Iterators  The following methods exist for creating iterators:       BBRS IP Software Group   iterator begin(). reverse_iterator rbegin(). const_reverse_iterator rend() const. const_iterator begin() const. const_iterator end() const. . Vector's iterators are random-access © 2004. The end() functions point to one element beyond the last element in the (forward or reverse) sequence. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. iterator end(). reverse_iterator rend().

if (ri == c.end(). return --i.rend()) return c.rbegin. They are not interchangeable. } 250 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.rend(). you might use:  BBRS IP Software Group template<class C> typename C::iterator find_last( C& c. v).base. For example.Vector Iterators    Note that a reverse_iterator is a distinct type from an iterator. c. The base() method of a reverse iterator returns an iterator that points to a position one beyond the position pointed to by the reverse_iterator. typename C::value_type v) { typename C::reverse_iterator ri = find(c. to find the last instance of a value. . typename C::iterator i = ri.

.Vector Element Access  Vectors support random-access to elements:  Unchecked access:   reference operator[] (size_type n). const_reference back() const. reference front(). reference at(size_type n). const_reference front() const. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. const_reference operator[] (size_type n) const.  Checked access (may throw out_of_range exception):   BBRS IP Software Group  First element:    Last element:   251 © 2004. reference back(). const_reference at(size_type n) const.

destructors and copy operators:   template <class T.Vector Construction and Destruction  There is a full set of constructors. const T& val = T(). // Construct a range of objects (In is an input iterator type) template<class In> vector(In first. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. class A=allocator<T> > class vector { public: // Construct an empty vector explicit vector(const A& = A()). In last. . const A& = A()). BBRS IP Software Group    252 © 2004. // Construct from another vector vector(const vector & x). // Construct vector with n copies of val explicit vector(size_type n. const A& = A()).

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. }. // Copy from n copies of val void assign(size_type n. const T& val).Vector Construction and Destruction  // Destructor ~vector().   BBRS IP Software Group 253 © 2004. // Copy from a range of objects (In is an input iterator) template<class In> void assign(In first. . In last).

v.Vector Stack Operations  The following stack operations exist:  Append to the end of the vector:  void push_back(const T& x). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.push_back(7).  Watch out for underflow . . // Undefined behavior . // Undefined behavior.don't pop an empty vector.pop_back(). This results in undefined behavior and may corrupt memory:  vector<int> v. v's state is now undefined v.  Remove the last element in the vector:  BBRS IP Software Group void pop_back().v's state was undefined 254 © 2004.

 Insert n copies of x before pos:  BBRS IP Software Group iterator insert(iterator pos. const T& x). In first.Vector List Operations  The following list operations exist for vectors:  Insert object x before position pos:  iterator insert(iterator pos. 255 © 2004. const T& x). size_type n. In last). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  Insert a range of objects before pos (In is an input iterator):  template<class In> void insert(iterator pos. .

BBRS IP Software Group  Delete all elements:  void clear(). 256 © 2004.  Delete a range of elements:  iterator erase(iterator first.Vector List Operations  Delete the element at position pos:  iterator erase(iterator pos). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . iterator last).

rbegin()+2). iterator and reverse-iterator // are different types c. // Bad. not // an iterator c. assumes too much about vector's // implementation c. How do you get an iterator from an index? For example. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.rbegin()+2).Addressing Vector Elements  List operations (among others) require iterators. // OK. // OK (deletes second-to-last element) c. if c's iterator supports + c.erase(c. adding 7 to a container makes no sense c.erase(&c[7]).erase((c. .erase(c.erase(c. how do you delete a specific element from a vector?   BBRS IP Software Group      c. // Bad. // Bad.erase(c.erase(c+7).base()). // Bad. but obscure 257 © 2004.back()).end()-2).begin() + 7). // OK. back() returns a reference.

Vector Size And Capacity  Get the number of elements stored in the vector  size_type size() const. void resize(size_type sz. . bool empty() const. size_type max_size() const. 258 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. size_type capacity() const.  Is the vector empty (has no elements)?   Get the maximum number of elements the vector can hold  BBRS IP Software Group  Set the size (initializing new elements to val)   Get the capacity (amount of memory currently allocated)   Make room for n elements (pre-allocation). throw a length_error exception if n > max_size()  void reserve(size_type n). T val=T()).

 BBRS IP Software Group    The == operator is overloaded for comparing two vectors. Similarly.More Vector Methods  Swap two vectors (more efficient than actually copying them to do a swap):  void swap(vector &). there are overloads for !=. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. The < operator is overloaded for comparing two vectors. They're equal if they have the same number of elements and matching pairs of elements all compare equal using their == operators. using lexicographic ordering. 259 . <=. > and >= These allow you to make a container of vectors © 2004.

 BBRS IP Software Group   260 © 2004. used for keeping a vector of Boolean values. since you can't take the address of a single bit. Your code should never assume any particular representation for any kind of iterator object.vector<bool>  There's a specialized version of the vector template. All vector operations work normally on vector<bool>. . Note that iterators for vector<bool> can not be implemented as pointers to the objects. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Generic Container Issues  Do not assume anything about the internal representation of a container.  BBRS IP Software Group 261 © 2004. If you assume any specifics. The standard doesn't define any specific representation. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. your code will break when ported to other platforms/compilers. .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. For example:  vector<foo *> vector<foo> Instead of:  262 © 2004.Generic Container Issues  Elements in a container are copies of the objects inserted. For example:  BBRS IP Software Group X& X::operator=(const X& a) { // copy all of a's members to this return *this. }  If it would be bad to make copies of objects. . you can make a container of pointers instead. Elements therefore require a compatible assignment operator.

When you retrieve the object. and RTTI may be used to determine the specific subclass (if this is necessary). You can't store a derived object in a container of base objects. however. because the copy constructor won't copy the derived object's fields. the original (derived) class data will be lost. .Generic Container Issues   BBRS IP Software Group  Another reason for making a container of pointers instead of objects is in order to preserve polymorphic behavior. virtual methods will continue to work as expected. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. store a pointer to a derived object in a container of pointers to the base class. 263 © 2004. You can. When you retrieve the object.

the < operator is used to define order.Generic Container Issues    BBRS IP Software Group Associative containers require that their elements can be sorted.y) || cmp(y.y) and cmp(y.z) 264 © 2004. If equiv(x. If this is not suitable.y) to be !(cmp(x. as long as the compare function is transitive:    cmp(x.y) and equiv(y. Some operations (like sort()) also require that elements can be sorted.x)).x) must be false If cmp(x.z) then cmp(x. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.z) then equiv(x. By default. then an alternative mechanism (involving a user-provided compare function) may be used. .z) Defining equiv(x.

int. map<char *. A compare function or overload for the < operator that calls strcmp may be used to make this work.q) < 0. This may lead to unexpected behavior if a container of char pointers is made. For example:  BBRS IP Software Group  struct Cstring_less { bool operator< (const char *p. Cstring_less> m. when used on C-strings (char pointers) will compare pointer values. 265 © 2004. not strings.Generic Container Issues    Note that the < operator. } }. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . const char *q) const { return strcmp(p.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. There are no subscripting operators. © 2004. Its methods are similar to vector. The capacity() and reserve() methods do not exist. but you should not make any assumption about the implementation. List iterators are bi-directional List may be thought of like a doubly-linked list. because it may be something else.List  Defined in the <list> header A list is a sequence optimized for insertion and deletion.   BBRS IP Software Group    266 .

iterator first. The following methods are provided for this:  Move all elements from x to before pos in this list without copying  BBRS IP Software Group void splice(iterator pos. 267 © 2004. iterator last). . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  Move *p from x to before pos in this list without copying  void splice(iterator pos. list& x. iterator p).List Splicing  List splicing allows you to move elements from one list to another without copying the objects. list& x.  Move a range of objects from x to before pos in this list without copying  void splice(iterator pos. list& x).

List Sort and Merge  In addition to splicing. and sorted lists may be merged together with the following methods:  Sort a list  void sort().  Merge sorted lists with a user-provided compare function  268 © 2004. lists may be sorted. Cmp). template<class Cmp> void sort(Cmp). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . template<class Cmp> void merge(list&.  Sort a list with a user-provided compare function  BBRS IP Software Group  Merge sorted lists  void merge(list&).

 Remove the first element  void pop_front().List Front Methods  All containers have the back() method to reference the last element. . 269 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. and the push_back()/pop_back() methods for stack operation. const_reference front() const.  Push a new element to the front of the list  void push_front(const T&). Lists provide similar methods for the front of the list:   Get a reference to the first element:   BBRS IP Software Group reference front().

Other List Methods  Remove an element without an iterator  void remove(const T& val). 270 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  Remove all elements that match a given predicate   Remove consecutive duplicate objects from a list  BBRS IP Software Group void unique().  Remove consecutive duplicate objects that match a given binary predicate  template<class Pred> void unique(Pred p). .  Reverse the order of a list  void reverse(). template<class Pred> void remove_if(Pred p).

. Push/pop operations at either end (front or back) are efficient (like a list) Subscript operations are efficient (like a vector) Insertions/deletions are inefficient (like a vector) Iterators are random-access   BBRS IP Software Group    271 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Deque  Defined in the <deque> header A deque is a double-ended queue.

There are three kinds of adaptors for the sequence templates:   BBRS IP Software Group  stack queue priority queue  Adaptors are made from other containers. but is an interface to another class. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . 272 © 2004.Sequence Adaptors   An adaptor is not a class.

push() and pop() © 2004. Only stack operations (push to one end. push_back(). and pop_back() are renamed with more conventional names: top().  BBRS IP Software Group   273 .Stack  Defined in the <stack> header An interface to its corresponding container (deque by default). Non-stack operations are eliminated. back(). pop from the same end) exist. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

vector<int> > s2. vector<foo> > foostack(foovec). stack <foo. since elements are copied:  vector<foo> foovec.Stack  Any container that implements back(). but it may be expensive. // made from vector  You can initialize a stack with another container. 274 © 2004. Examples:    BBRS IP Software Group stack<char> s1. . push_back() and pop_back() may be used in a stack. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // made from deque stack<int.

 BBRS IP Software Group   275 © 2004.Queue  Defined in the <queue> header An interface to its corresponding container (deque by default) Non-queue operations are eliminated. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Only queue operations (push to one end. pop from the other end) exist. push_back() and pop_front() are renamed with more conventional names: push() and pop(). .

Queue  Any container that implements front(). . push_back() and pop_front() can be used in a queue. back(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Note that this excludes vector  BBRS IP Software Group 276 © 2004.

and top() returns the largest element A comparison function may be provided if the < operator is not appropriate © 2004. instead of front() By default. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Unlike queue. elements are compared with the < operator.Priority Queue  Defined in the <queue> header Like a queue. but elements are kept sorted. top() retrieves the next-to-be-popped element.   BBRS IP Software Group   277 .

Associative Containers   Associative containers store objects with key values.keys not unique set . sorted by key.a sequence of keys only. keys are unique multimap . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. keys are unique multiset . . The different kinds of associative containers are:    BBRS IP Software Group  map .keys are not unique  Most associative container operations are implemented by map (much like most sequence operations are implemented by vector) 278 © 2004.a sequence of key/value pairs.

Sometimes referred to as a dictionary. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. A map is a sequence of key/value pairs. Each key in a map is unique. Elements are kept sorted by their keys  BBRS IP Software Group    279 © 2004. Similar in concept to our BBT trees. .Map  Defined in the <map> header An associative container. Iterators are bi-directional.

const_iterator reverse_iterator. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.the type of a key mapped_type . . const_reference iterator.the type of each key/value pair key_compare . const_reverse_iterator 280 © 2004.the type of the data value_type .Map Types  Map defines the following typedefs as a part of the template:     BBRS IP Software Group       key_type .the comparison function allocator_type size_type difference_type reference.

. mapped_type>. but the values they refer to are key/value pairs.  BBRS IP Software Group   281 © 2004.Map Iterators  Map's iterators work like sequence iterators. the first element is the key and the second element is the value. Dereferencing a map iterator will return an object of the template class pair<key_type. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. This object class is also the value_type definition In each pair.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. second(p.second) {} }.Pairs   Defined in the <utility> header The two elements are named first and second  The public part of the class definition is:  BBRS IP Software Group template<class T1. 282 © 2004.first). pair() : first(T1()). typedef T2 second_type. second(y) {} template<class U. . T1 first. const T2 &y) : first(x). class T2> struct std::pair { typedef T1 first_type. second(T2()) {} pair(const T1& x. T2 second.V>& p) : first(p. class V> pair(const pair<U.

. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. int> m. assigned 7 // y is 7 // "Henry" is now 9 // "Harry" is now 37 283 © 2004. x is 0 // "Harry" is initialized to 0. // "Henry" is initialized to 0. an element is added to the map with default values For example:   map<string.  BBRS IP Software Group If the key is not found. m["Harry"] = 7. int x = m["Henry"]. m["Henry"] = 9. m["Harry"] = 37. int y = m["Harry"].Map Element Access  The subscript operator is used to retrieve items from a map:  mapped_type& operator[](const key_type& k).

const A& = A()). .  BBRS IP Software Group    284 © 2004. In addition:  // Construct an empty map explicit map(const Cmp& = Cmp(). In last. // Assignment operator overload map &operator= (const map&). // Construct from another map map(const map&). // Construct from a list of key/value pairs (In is an input iterator) template <class In> map(In first. const A& = A()). // Destructor ~map(). const Cmp& = Cmp().Map Constructors  All the usual constructors are provided. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

String_cmp> m4(String_cmp(literary)). Nocase> m2. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. int> m1. A map can be created using other compare functions. Use String_cmp (to be constructed by map) instead map<string. Use a String_cmp object that we constructed ourselves map<string. String_cmp> m3. keys are compared using the < operator. Use Nocase (to be constructed by map) instead map<string. int. int. For example:  Default comparison class (less<string>) map<string.  BBRS IP Software Group   285 © 2004. int. .Map Compare Functions    By default.

Map Compare Functions 

The functions used for comparing keys and values (which are key/value pairs) are publicly available. They are called key_comp() and value_comp(), respectively. This allows you to pass one map's comparison function to another. For example:   

BBRS IP Software Group

void f(map<string, int>& m) { // mm compares keys with < map<string, int> mm; // mmm compares keys with whatever function m uses map<string, int> mmm(m.key_comp()); }

286

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Map Operations 

Find the element (or first element, for multimap/multiset) with a given key: 


iterator find(const key_type& k); const_iterator find(const key_type& k) const;

BBRS IP Software Group 

Find the number of elements with a given key: 

size_type count(const key_type& k) const;

287

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Map Operations 

Find the first element with a key greater than or equal to a given key: 


iterator lower_bound(const key_type& k); const_iterator lower_bound( const key_type& k) const;

BBRS IP Software Group 

Find the first element with a key greater than a given key: 


iterator upper_bound(const key_type& k); const_iterator upper_bound( const key_type& k) const;

288

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Map Operations 

Find both the lower bound and upper bound together in a pair (lower bound is first, upper bound is second):  

pair<iterator, iterator> equal_range(const key_type& k); pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

BBRS IP Software Group

289

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Map List Operations 

Like with sequences, there are list-type operations: 

Insert a key/value pair: 

pair<iterator, bool> insert(const value_type &val);

BBRS IP Software Group 

Insert at a given position (pos is a hint for optimization): 

iterator insert(iterator pos, const value_type &val); 

Insert elements from a sequence (In is an input iterator): 

template<class In> void insert(In first, In last);

290

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Map List Operations 

Erase an element 

void erase(iterator pos); 

Erase all elements with a given key (return value is the number actually erased): 

size_type erase(const key_type& k);

BBRS IP Software Group 

Erase a range of elements: 

void erase(iterator first, iterator last); 

Erase all elements: 

void clear();

291

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Map Miscellaneous Functions  Get the number of elements  size_type size() const. BBRS IP Software Group  Returns true if the map is empty (has no elements)  bool empty() const. . 292 © 2004.  Get the size of the largest possible map  size_type max_size() const.

 Two maps may be compared using the ==. . and >= operators Although these are not terribly useful. >. they allow us to make containers that contain maps BBRS IP Software Group  293 © 2004. !=.Map Miscellaneous Functions  Swap two maps:  void swap(map&). <. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. <=.

There is no subscript operator in a multimap. The insert() function returns an iterator instead of a pair:   BBRS IP Software Group  iterator insert(const value_type&). In addition.Multi-Map  A multimap can do everything a map can do. since it is a meaningless concept. multiple elements may share the same key. 294 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

insert(make_pair("x". 4)). Cstring_less> mm. 295 © 2004. // No effect // m["x"] == 4 BBRS IP Software Group  multimap<char *.insert(make_pair("x".insert(make_pair("x". m.insert(make_pair("x". 4)).Multi-Map Example  map<char *. Cstring_less> m.5). . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // mm now holds both ("x". int. 5)). int. mm. 5)). mm. m.4) and ("x".

value_type is the same as key_type value_compare is the same as key_compare There is no subscript operator  BBRS IP Software Group    296 © 2004. You can only access keys.Set  Defined in the <set> header A Set is like a map. except that no values are stored. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

with one exception: The insert() function returns an iterator instead of a pair:   BBRS IP Software Group  iterator insert(const value_type&). .Multi-Set  A multiset is a set that allows duplicate keys A multiset's interface is identical to set's. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 297 © 2004.

Almost-Containers 

There are four other kinds objects that are not containers, but share many similar properties to containers. These are: 
 

BBRS IP Software Group 

String Valarray Bitset Array

298

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

String 

A string provides subscripting, random-access iterators and most of the same interface as a container, but it does not provide for a wide selection of types as elements. Strings are optimized for use as a string of characters and has methods that allow them to be used in places where string operations are traditionally used Strings have an associated "character traits" object which defines the properties of the character type that the string stores. This allows for use with non-standard character encodings.
© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 

BBRS IP Software Group 

299

Basic String 

Defined in the <string> header 

BBRS IP Software Group

template<class Ch, class Tr=char_traits<Ch>, class A=allocator<Ch> > class std::basic_string { ... } 

There are two convenience typedefs provided as well: 


typedef basic_string<char> string; typedef basic_string<wchar_t> wstring;

300

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

Differences Between String and Vector 

Most of basic_string's functionality is the same as vector's. The similarities will not be discussed here. Some of the differences are:  

The iterators are not range-checked There is no front() or back(). The subscript operator and length method must be used instead. For example: 

BBRS IP Software Group 

string foo; // (Assume this to be initialized) char first_char = foo[0]; char last_char = foo[foo.length()-1];

301

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

String Constructors 

Construct an empty string 

explicit basic_string(const A& a = A()); 

Construct from another string (or a subset of another string) 

basic_string(const basic_string &s, size_type pos=0, size_type n=npos, const A& a = A()); basic_string(const Ch* p, const A& a = A()); basic_string(const Ch* p, size_type n, const A& a = A()); basic_string(size_type n, Ch c, const A& a = A());

BBRS IP Software Group 

Construct from a C-string  

Construct from a C substring  

Construct initialized to a repeating character  

302

Construct from an iterator (In is an input iterator) 

template<class In> basic_string(In first, In last, © 2004. The Copyright in this document belongs to Marconi and no part of const A& a = A()); this document should be used or copied without their prior written permission.

String Constructors 

String destructor: 

~basic_string(); 

"All characters" marker: 

static const size_type npos;

BBRS IP Software Group

303

© 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

// Error . 'a'). // Initialized to "obi" 304 © 2004. // OK s7(s5. // Empty string s1 = 'a'.no conversion from int s3(7). // OK s6 = s5.2. // Error .no one-argument constructor s4(7. . // Empty String s00 = "". The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.3).String Construction Examples       BBRS IP Software Group    string string string string string string string string string s0.no conversion from char s2 = 7. // Error . // Initialized to "aaaaaaa" s5 = "Foobie".

// Some external C string string s8(p+7.. p[8] and p[9] string s9(p. // Same. v. // Initialized to p[7]. 7.String Construction Examples   char *p = . . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.  BBRS IP Software Group  Note that this last example is very generic. string s10(v. 305 © 2004. 3).. The iteratorbased constructor will work on any iterator that dereferences to a type that can be converted to char.... but more expensively vector<char> v = ..end()).begin(). 3).

The main categories of string manipulation methods are:   BBRS IP Software Group       Assignment Comparison Append Insert Concatenate Find Replace Substring 306 © 2004.String Manipulations   There are a very large number of methods for manipulating strings. given the huge number of overloads that exist. They are far too numerous to list here. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

Copy the characters to an array (does not append null!):   size_type copy(Ch *p. const Ch* c_str() const. Do not cache the pointers. Do not free the memory. .String Conversion To C-String  Return an array of characters:  const Ch* data() const. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. size_type n.  Return a null-terminated string of characters:   BBRS IP Software Group Note that the string owns the returned values from data() and c_str(). The memory may become invalid after the next non-const method call on the string. 307 © 2004. size_type pos=0) const.

Ch eol). Class A> basic_istream<Ch.String I/O    The << method is overloaded to write a string to an output stream The >> method is overloaded to read a string from an input stream The getline method reads a line from an input stream (using a user-specified EOL character):  BBRS IP Software Group template<class Ch.Tr>&. basic_string<Ch. class Tr. .  If eol is not specified. '\n' is used 308 © 2004.Tr.A>&.Tr>& getline(basic_istream<Ch. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

ValArray  A ValArray is a vector that is optimized for use in high speed numerical computing.  BBRS IP Software Group  309 © 2004. The only standard container operations that are applicable to valarray are size (get the number of elements) and subscript (to read/write elements. although there are typically many commonalities. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .) Because the goal of a valarray is to make vector math as fast as possible. other methods are implementation dependant.

valarray shift(int i) const. valarray apply(T f(const T&)) const. %=. ^=.  Shift/rotate (cyclic shift) all elements:    Apply a function to each element:   310 © 2004. += .Typical ValArray Methods  Common valarray methods include:  v[i] *= arg for every element:  valarray& operator*=(const T& arg). .   (similar overloads for /=. valarray cshift(int i) const. <<= and >>=) Sum up all elements:  BBRS IP Software Group T sum() const. |=. &=. valarray apply(T f(T)) const. -=. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. but we won't go into them because they are typically only useful for vector arithmetic (such as signal processing or games.) 311 © 2004. const. const. const. . BBRS IP Software Group  There are many more things you can do with a ValArray.Typical ValArray Methods  Unary operations on each element     valarray& valarray& valarray& valarray& operator-() operator+() operator~() operator!() const.

Bit-Set  Defined in the <bitset> header Designed to replace bit-flag manipulation. . bitset<N> is a fixed-size array of N bits A bitset differs from vector<bool> due to its fixed size A bitset differs from a set because it is indexed by integer instead of associative keys   BBRS IP Software Group   312 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. public: ~reference(). 313 © 2004. reference& operator=(const reference&). reference& flip(). reference& operator=(bool x).Bit-Set  Because you can't have a pointer to a bit. reference(). bitset defines a "reference to bit" class to be used where references are necessary:  BBRS IP Software Group template<size_t N> class std::bitset { public: class reference { friend class bitset. }. . }. bool operator~(). operator bool() const.

Bit-Set  Bitsets differ from other container classes (mostly for historical reasons).2). . In other words the value of b[i] is pow(i. A bitset may be thought of as an N-bit binary number  314 © 2004.   Using an invalid index throws an out_of_range exception There are no iterators BBRS IP Software Group  Bit positions are numbered right-to-left. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

A>::npos).  Initial bits derived from a value  bitset(unsigned long val).A>::size_type pos = 0.Tr.Tr. class A> explicit bitset(const basic_string<Ch. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 315 © 2004.Bit-Set Constructors  Default constructor (all bits zero)  bitset(). .A>& str. basic_string<Ch. basic_string<Ch.A>::size_type n = basic_string<Ch.Tr. BBRS IP Software Group  Initial bits from a string (characters '1' and '0')  template<class Ch. class Tr.Tr.

// All-zeros b2 = 0xaaaa. .Bit-Set Construction Examples       BBRS IP Software Group   bitset<10> bitset<16> bitset<32> bitset<10> bitset<10> bitset<10> bitset<10> bitset<10> b1. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // 0011011101 b7("n0g00d"). 8). // 1010101010101010 b3 = 0xaaaa. 2. // invalid_argument exception b8 = "n0g00d". // 0111011110 b6("10110111011110". // 00000000000000001010101010101010 b4("1010101010"). 4). // 1010101010 b5("10110111011110". // Err: no char* to bitset conversion 316 © 2004.

Bit-Set Manipulation  The following operators are used for accessing and manipulating the bits in a bitset:  Bit-access (subscript)  reference operator[](size_t pos). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. . bitset& operator|=(const bitset& s).  Logical operators    BBRS IP Software Group  Logical shift   317 © 2004. bitset& operator>>=(size_t n). bitset& operator&=(const bitset& s). bitset& operator^=(const bitset& s). bitset& operator<<=(size_t n).

 Set bits to 0   BBRS IP Software Group  Toggle bits    Make complemented/shifted set    318 © 2004. // b[pos]=0 bitset& flip(). // Toggle all bits bitset& flip(size_t pos). . // Toggle b[pos] bitset operator~() const. bitset operator<<(size_t n). // Set all bits to 0 bitset& reset(size_t pos). bitset operator>>(size_t n). int val=1). // b[pos]=val bitset& reset(). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. // Set all bits to 1 bitset& set(size_t pos.Bit-Set Manipulation  Set bits to 1   bitset& set().

Class Tr.  Make a string from the bitset  BBRS IP Software Group  Get the number of bits in the set   Get the number of bits that are set to 1  319 © 2004.Tr. . size_t count() const. template<class Ch. size_t size() const. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Class A> basic_string<Ch.A> to_string() const.Bit-Set Operations  Make an unsigned long from the bitset (throws overflow_error exception if there are too many significant bits)  unsigned long to_ulong() const.

Bit-Set Operations  Comparison   bool operator==(const bitset& s) const. bool any() const. bool operator!=(const bitset& s) const.  Is the bit at position pos set?   Are any bits set?  BBRS IP Software Group  Are all of the bits clear?  320 © 2004. bool test(size_t pos) const. bool none() const. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

There are subscripting operators for element access and random-access iterators (in the form of pointers).Array  An array is the same in C++ as in C. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. Arrays don't know their own size and do not have any of the usual member operations and types  BBRS IP Software Group  321 © 2004.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. 322 © 2004. . T& reference. T* const_iterator. } iterator begin() { return v. operator T*() { return v. }. } .Arrays  It is possible. } iterator end() { return v+max. T* iterator. typedef typedef typedef const typedef typedef const int max> struct c_array { T value_type. For example:  BBRS IP Software Group template<class T. however to create a template that wraps an array to allow basic container functionality. T v[max].. } ptrdiff_t size() const { return max. T& const_reference. } reference operator[](size_t i) { return v[i]..

Container Operation Summary  The following table summarizes the standard container operations: Subscript [] vector list deque stack queue priority queue map multimap set multiset string array valarray bitset O(log(n)) O(log(n)) O(log(n))+ O(log(n))+ O(log(n))+ O(log(n))+ O(n)+ O(n)+ const+ const const List operations O(n)+ const O(n) Front operations const const const O(log(n)) Back (stack) operations const+ const const const+ const+ O(log(n)) Bi Bi Bi Bi Ran Ran Ran Iterators Ran Bi Ran BBRS IP Software Group const const const const 323 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .

marconi. www.Introduction to C++ Numerics BBRS IP Software Group © 2003. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.com .

which we've previously discussed Section 22. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.4 of The C++ Programming Language explains in great detail the things that can be done with ValArrays and related classes  BBRS IP Software Group 325 © 2004.Vector Arithmetic  Vector arithmetic is performed using the valarray class. .

float. Defined in the <complex> header It is a template in order to allow complex numbers to be based on any scalar type (e.g. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. and long double)  BBRS IP Software Group  326 © 2004. .Complex  The standard C++ library also includes a complex arithmetic library. double.

template<class X> complex<T>& operator=(const complex<X>&). 327 © 2004. }. . The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. template<class X> complex(const complex<X>&a). *=. // Similarly: +=. complex(const T& r = T(). T imag() const. BBRS IP Software Group T real() const.. const T& i = T())..The Complex Class  template<class T> class std::complex { public: typedef T value_type. -=. complex<T>& operator=(const T&z). /= // .

.Complex Unary/Binary Operators  Binary operators  complex<T> operator+(const const complex<T> operator+(const complex<T> operator+(const complex<T>&. complex<T>&). *. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. const T&). /. == and != BBRS IP Software Group  Unary operators:  complex<T> operator+(const complex<T>&). complex<T>&. T&.  Similar operators for -. const complex<T>&). 328 © 2004. complex<T> operator-(const complex<T>&).

const T& theta).Complex Coordinate Functions  Retrieve Cartesian components:   T real(const complex<T>&). // square of abs()  Generate conjugate:  BBRS IP Software Group  Construct from polar coordinates:   Retrieve polar values:    329 © 2004. . complex<T> conj(const complex<T>&). T abs(const complex<T>&). complex<T> polar(const T& rho. T imag(const complex<T>&). // rho T arg(const complex<T>&). // theta T norm(const complex<T>&). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

complex<T> pow(const complex<T>&.Complex Mathematical Functions  Trigonometric functions:   complex<T> sin(const complex<T>&). 330 © 2004. int). sqrt. const complex<T>&). Similarly for sinh. complex<T> pow(const T&. log and log10  Exponentiation:    BBRS IP Software Group  complex<T> pow(const complex<T>&. . exp. cos. const T&). The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. const complex<T>&). tan. tanh. cosh. complex<T> pow(const complex<T>&.

.y) Complex numbers may be read as either x. (x). Complex numbers are written in the form (x. or (x. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Complex Stream I/O  Overloads for the << and >> operators exist to allow complex numbers to be read/written from/to iostreams.y)  BBRS IP Software Group  331 © 2004.

.Complex Specializations  Specialized templates exist for:    complex<float> complex<double> complex<long double> BBRS IP Software Group  This is done to restrict/facilitate type conversion and to provide opportunities for optimized libraries. 332 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

.Generalized Numerics  The <numeric> header provides a few generalized algorithms that perform common operations on arbitrary numeric types:    BBRS IP Software Group  accumulate() inner_product() adjacent_difference() partial_sum() 333 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. class T> T accumulate(In first. . T init) { while(first != last) init = init + *first++. In last. } 334 © 2004.Accumulate  The accumulate algorithm produces the sum of all elements its given (via two input iterators):  BBRS IP Software Group template<class In. return init.

class BinOp> T accumulate(In first. } 335 © 2004. T init. return init. In last. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. *first++). BinOp op) { while(first != last) init = op(init. class T.Accumulate  A more generalized version of accumulate also exists. that allows any binary operation to be performed on the set of elements:  BBRS IP Software Group template<class In. .

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.Inner Product  An inner product is the result of summing the product of two sequences. class In2. } 336 © 2004. and all of these products are summed up together:  BBRS IP Software Group template<class In. class T> T inner_product(In first. That is. In last. In2 first2. T init) { while(first != last) init = init + (*first++ * *first2++). items at identical indices are multiplied together. . return init.

*first2++)). BinOp2 op2) { while(first != last) init = op(init. return init. class BinOp2> T inner_product(In first. class T. class In2.Inner Product  A more generalized version of inner_product also exists. BinOp op. . } 337 © 2004. In last. that allows any two binary operations to be used in place of multiplication and addition:  BBRS IP Software Group template<class In. op2(*first++. In2 first2. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. T init. class BinOp.

In last.... Out result.d.d-c. In last... class BinOp> Out adjacent_difference(In first.Adjacent Difference   Given a sequence of input values.c-b. .  338 © 2004. BinOp op).b-a. class Out> Out adjacent_difference(In first.. Input sequence {a. class Out. generate a sequence that consists of the differences between adjacent values.} produces {a.b. template <class In. Out result).c.} A basic function and one that uses a generalized operation (instead of subtraction) are provided for this:  BBRS IP Software Group template <class In. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.

In last.a+b+c+d. Out result). class Out> Out partial_sum(In first.. Out result.a+b+c. class BinOp> Out partial_sum(In first.....c.d.} A basic function and one that uses a generalized operation (instead of addition) are provided for this:  BBRS IP Software Group template <class In.  339 © 2004. Input sequence {a. template <class In.a+b..} produces {a. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. .b. class Out.Partial Sum   A partial sum allows us to compute the end result of a set of incremental changes. In last. BinOp op).

The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission. www.com .marconi.Introduction to C++ Conclusion BBRS IP Software Group © 2003.

.Conclusion  This presentation covers all of the basics There are more details not covered There is no substitute for experience What are you waiting for? Start writing some code!   BBRS IP Software Group  341 © 2004. The Copyright in this document belongs to Marconi and no part of this document should be used or copied without their prior written permission.