+ All Categories
Home > Documents > C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing...

C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing...

Date post: 08-May-2018
Category:
Upload: doanbao
View: 224 times
Download: 2 times
Share this document with a friend
263
1 C++ Design Essentials From basic design to advanced implementations Broad list of Definitions, Explanations and Examples Compilation of many online sources Gregg Roeten CLASSES, TEMPLATES - SUMMARY ........................................................................................ 8 C++ CLASS DEFINITIONS: ......................................................................................................... 9 Define C++ Objects: ........................................................................................................................................... 9 Accessing the Data Members:........................................................................................................................ 9 Member Function........................................................................................................................................ 11 Pointer to Member function ........................................................................................................................ 14 Non Member Function ................................................................................................................................ 16 C++ Class access modifiers ............................................................................................................................... 16 The public members: ................................................................................................................................... 17 The private members: ................................................................................................................................. 17 The protected members: ............................................................................................................................. 19 Initialize a variable ........................................................................................................................................... 20 Reference Variable .................................................................................................................................. 20 Whats the difference between a Reference Variable and a Pointer?......................................................... 20 Implicit Conversion/Coercion ........................................................................................................................... 20 C++ CLASS CONSTRUCTOR AND DESTRUCTOR ................................................................ 21 Constructors Empty, Copy, Char, Destructor ................................................................................................. 24 Calling constructor without new .................................................................................................................. 25 The Class Constructor: ..................................................................................................................................... 25 Parameterized Constructor: ......................................................................................................................... 26 Using Initialization Lists to Initialize Fields: ................................................................................................... 27 The Class Destructor: ....................................................................................................................................... 28 C++ Copy Constructor .................................................................................................................................. 30 Delegation................................................................................................................................................... 33 Override...................................................................................................................................................... 34 C++ Inline Functions......................................................................................................................................... 36 C++ this Pointer ........................................................................................................................................... 36 Pointer to C++ classes ...................................................................................................................................... 38 UNARY OPERATORS OVERLOADING IN C++ ...................................................................... 39 FRIEND FUNCTIONS ................................................................................................................ 40 FRIEND CLASSES....................................................................................................................... 42 friend declaration ............................................................................................................................................ 43 Description.................................................................................................................................................. 43 MEMORY STRUCTURE............................................................................................................. 46 Stack and Heap ............................................................................................................................................... 46 Heap, Stack, Global, Static Variable Memory layout .......................................................................................... 47
Transcript
Page 1: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

1

C++ Design Essentials From basic design to advanced implementations

Broad list of Definitions, Explanations and Examples

Compilation of many online sources

Gregg Roeten

CLASSES, TEMPLATES - SUMMARY ........................................................................................ 8

C++ CLASS DEFINITIONS: ......................................................................................................... 9 Define C++ Objects: ........................................................................................................................................... 9

Accessing the Data Members: ........................................................................................................................ 9 Member Function........................................................................................................................................ 11 Pointer to Member function ........................................................................................................................ 14 Non Member Function ................................................................................................................................ 16

C++ Class access modifiers ............................................................................................................................... 16 The public members: ................................................................................................................................... 17 The private members: ................................................................................................................................. 17 The protected members: ............................................................................................................................. 19

Initialize a variable ........................................................................................................................................... 20 Reference Variable .................................................................................................................................. 20 Whats the difference between a Reference Variable and a Pointer?......................................................... 20

Implicit Conversion/Coercion ........................................................................................................................... 20

C++ CLASS CONSTRUCTOR AND DESTRUCTOR ................................................................ 21 Constructors Empty, Copy, Char, Destructor ................................................................................................. 24 Calling constructor without new .................................................................................................................. 25

The Class Constructor: ..................................................................................................................................... 25 Parameterized Constructor: ......................................................................................................................... 26 Using Initialization Lists to Initialize Fields: ................................................................................................... 27

The Class Destructor: ....................................................................................................................................... 28 C++ Copy Constructor .................................................................................................................................. 30 Delegation ................................................................................................................................................... 33 Override ...................................................................................................................................................... 34

C++ Inline Functions ......................................................................................................................................... 36 C++ this Pointer ........................................................................................................................................... 36

Pointer to C++ classes ...................................................................................................................................... 38

UNARY OPERATORS OVERLOADING IN C++ ...................................................................... 39

FRIEND FUNCTIONS ................................................................................................................ 40

FRIEND CLASSES....................................................................................................................... 42 friend declaration ............................................................................................................................................ 43

Description .................................................................................................................................................. 43

MEMORY STRUCTURE ............................................................................................................. 46 Stack and Heap ............................................................................................................................................... 46 Heap, Stack, Global, Static Variable Memory layout .......................................................................................... 47

Page 2: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

2

memcpy() vs memmove() ....................................................................................................................... 47 Storage Class Specifiers .................................................................................................................................... 48 Lifetime and Scope ........................................................................................................................................... 48 x86 Architecture .............................................................................................................................................. 51

PROCESSOR'S STACK FRAME LAYOUT ........................................................................................................... 52 Heap Debugger, Memory leak = Valgrind ........................................................... Error! Bookmark not defined.

ABSTRACT DATA TYPE (ADT) ............................................................................................... 53 ADT is a interface .................................................................................................................................... 53

ADT examples .................................................................................................................................................. 53

DATA STRUCTURES .................................................................................................................. 54 Big-O Taxonomy .......................................................................................................................................... 54 Containers ................................................................................................................................................... 54

ADT/DATA STRUCTURE IMPLEMENTATION ..................................................................... 55 Interface (*.h): ........................................................................................................................................ 55 Implementation (*.cpp) .......................................................................................................................... 55

Operations ....................................................................................................................................................... 55 Access Function ...................................................................................................................................... 55 Modification function ............................................................................................................................. 55 Algorithm ............................................................................................................................................... 55

Data Structure Organization ............................................................................................................................. 55 ADT / Data Structure doesn’t care about the implementation .................................................................. 56

ex ................................................................................................................................................................ 56 Implementing a stack ADT in C++ ................................................................................................................. 56 Implementing a stack ADT in C++ with STL ................................................................................................... 56 ex ................................................................................................................................................................ 56

How to choose the right Data Structure? Match Characteristics. ...................................................................... 58 ADT Average Execution Time ....................................................................................................................... 60

Average and Worst Execution Times ........................................................................................................ 61 Data Structures implemented as Array ............................................................................................................. 62

Array ...................................................................................................................................................... 62 declare ................................................................................................................................................... 62 size ......................................................................................................................................................... 62 find ......................................................................................................................................................... 62 assign one array to another ..................................................................................................................... 62

Stack implemented as Array ............................................................................................................................. 63 declare ................................................................................................................................................... 63 Access and Modify .................................................................................................................................. 63 Add ........................................................................................................................................................ 63 Remove .................................................................................................................................................. 64

Queue implemented as Array ........................................................................................................................... 65 Real Life Example .................................................................................................................................... 65 Declare ................................................................................................................................................... 65 Add ........................................................................................................................................................ 65 Remove .................................................................................................................................................. 65 Resize since it is an array ..................................................................................................................... 65

Implement Deque as Array ............................................................................................................................... 66 Declare ................................................................................................................................................... 66 Get, Set .................................................................................................................................................. 66

Implement Data Structures as Linked List section ............................................................................................. 67 Singly Linked List .............................................................................................................................................. 67

List ......................................................................................................................................................... 67 head and tail ........................................................................................................................................... 67 Add(x) at tail though............................................................................................................................. 67 Remove at head like pop ..................................................................................................................... 68 Push(x) easily implement stack with push and pop .................................................................................. 68 Pop easily implement stack with push and pop ................................................................................... 68

Page 3: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

3

example ........................................................................................................................................................... 69 Linked_List_Imp_Class_ptr_to_next_Class ........................................................................................................ 69

Print Linked List Elements in Reverse order ............................................................................................. 69 Implement Data Structures as Sets section ....................................................................................................... 70

Sets ........................................................................................................................................................ 70 Hash Tables............................................................................................................................................. 70

Chained Hash Table .......................................................................................................................................... 70 Define Hash Table ................................................................................................................................... 71 Add ........................................................................................................................................................ 71 Remove .................................................................................................................................................. 71 Find ........................................................................................................................................................ 72

Binary Trees ..................................................................................................................................................... 73 B-Trees (Binary Trees): ............................................................................................................................ 73 Binary Tree Search (BST) ......................................................................................................................... 74 Implementation #1 ................................................................................................................................. 74 Binary Tree implementation #2 ............................................................................................................... 76

How to print all Tree nodes at at given level ................................................................................................. 78 1) Print all nodes at a given level (printGivenLevel) .................................................................................. 78 2) print level order traversal of the tree (printLevelorder). ....................................................................... 79

Red-Black binary search tree ............................................................................................................................ 79 Heaps binary tree ....................................................................................................................................... 81

Heap....................................................................................................................................................... 81 Implentation ........................................................................................................................................... 81 Add ........................................................................................................................................................ 82 Remove .................................................................................................................................................. 83

SORTING ALGORITHMS .......................................................................................................... 84 Merge-sort ...................................................................................................................................................... 84

Implementation ...................................................................................................................................... 84 Merge ..................................................................................................................................................... 84

Quicksort ......................................................................................................................................................... 85 Implementation ...................................................................................................................................... 85

Heap-sort ........................................................................................................................................................ 86 Implementation ...................................................................................................................................... 86

STANDARD TEMPLATE LIBRARY.......................................................................................... 87 Standard Template Library is a set of well structured Generic ADT’s 2 categories........................................ 87 Summary of ADT, Data Structure, Interface and Implementation ...................................................................... 88

CONTAINER CLASS TEMPLATES ........................................................................................... 94 1. Container Sequential .................................................................................................................................... 95

Sequential Constructors .......................................................................................................................... 97 Inserting and erasing anywhere in a sequence......................................................................................... 97 For all sequences: inserting/removing at end .......................................................................................... 97

2. Container Associative ................................................................................................................................... 98 set............................................................................................................................................................... 98 multiset....................................................................................................................................................... 98 map ............................................................................................................................................................ 98 multimap .................................................................................................................................................... 99

Dictionary Implementation languages ................................................................................................... 100 Unordered associative containers................................................................................................................... 100 Container Adapters ........................................................................................................................................ 100 Iterators ......................................................................................................................................................... 102

Implementing iterators for the array .......................................................................................................... 103 Implementing iterators for the linked list ................................................................................................... 104

Reverse Iterators ............................................................................................................................................ 109

ALGORITHMS IN STL ........................................................................................................... 111

Page 4: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

4

SORT ALGORITHMS .............................................................................................................. 112

TEMPLATES ............................................................................................................................ 115 Function templates ........................................................................................................................................ 115

Function Template w/ Multiple Parameters, order of parameters determine output .................................. 117 Class Templates.............................................................................................................................................. 120

Template Specification............................................................................................................................... 120 Members of class templates ...................................................................................................................... 125 Nested Class Templates ............................................................................................................................. 126

Templates and Friends ................................................................................................................................... 128 Template specialization ............................................................................................................................. 129 Non-type parameters for templates ........................................................................................................... 130

Template friends ............................................................................................................................................ 131 Member Initialization: .................................................................................................................................... 132

What is the difference between Initializing and Assignment inside a constructor? ...................................... 132 When do you HAVE TO use Member Initializer list? .................................................................................... 133

ACCESSING OBJECT MEMBERS VARIABLES AND METHODS ...................................... 135 pointer .......................................................................................................................................................... 135 instance ......................................................................................................................................................... 135 class/struct or namespace .............................................................................................................................. 135 Const-ness ..................................................................................................................................................... 138

cast away const-ness ................................................................................................................................. 139 Namespace .................................................................................................................................................... 139

STATIC CLASS MEMBER, STATIC FUNCTION MEMBER ................................................ 141 Static member variables ................................................................................................................................. 141 Static member functions ................................................................................................................................ 141 1) Static Member Functions ........................................................................................................................... 143 2) Non-Static Member Functions .................................................................................................................... 143 Static Function Members: (Static Member Function) ...................................................................................... 143

How to access static variables in class ........................................................................................................ 145 private static constant for a class ............................................................................................................... 148 Static members of a C++ class .................................................................................................................... 148

CALLBACK / FUNCTION POINTER..................................................................................... 153 Parse a function pointer ................................................................................................................................. 154 Use a function pointer ................................................................................................................................... 154

Declare function pointer ............................................................................................................................ 154 Assign function pointer.............................................................................................................................. 154

Parse the function pointer with args ............................................................................................................... 154 Define a function pointer and initialize to NULL ......................................................................................... 154 Assign an address to a Function Pointer ..................................................................................................... 154 Invoke a callback ....................................................................................................................................... 155 Pass a function pointer as a function's calling argument ............................................................................. 155 How to Return a Function Pointer ? ........................................................................................................... 155 How to Use Arrays of Function Pointers ?................................................................................................... 156

C++11 NEW FUNCTIONALITY ............................................................................................ 158 auto Variables - Compiler knows what you mean ............................................................................................ 158 Range-Based for Loop .................................................................................................................................... 158 Initializer Lists ................................................................................................................................................ 158 Lambda Functions .......................................................................................................................................... 158

Inline methods in other methods ............................................................................................................... 158 Capturing external local variables .............................................................................................................. 159 Design your APIs with lambdas in mind ...................................................................................................... 159 Lambdas and Function Pointers ................................................................................................................. 159

Page 5: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

5

&& Enable Move Construction................................................................................................................... 159 Delegating Constructors ............................................................................................................................ 159 Alias Templates ......................................................................................................................................... 160 Non-Static Data Member Initializers........................................................................................................... 160 New Smart Pointers ................................................................................................................................... 160 Function Return Type Deduction................................................................................................................ 160 Override and final...................................................................................................................................... 160

C++11 LAMBDA FUNCTIONS .............................................................................................. 161

AUTO VARIABLE (AUTOMATIC VARIABLE) .................................................................. 163 Function objects ........................................................................................................................................ 164

C++14 NEW FUNCTIONALITY ............................................................................................ 165 Lambda functions ...................................................................................................................................... 165 Constexpr .................................................................................................................................................. 165 Type deduction ......................................................................................................................................... 165

FUNCTORS: FUNCTION OBJECTS IN C++.......................................................................... 168 Initialization list ......................................................................................................................................... 170 Using Initialization Lists to Initialize Fields .................................................................................................. 173 Initialization Lists and Scope Issues ............................................................................................................ 173 When Else do you Need Initialization Lists? ................................................................................................ 174 Initialization Lists and Exceptions ............................................................................................................... 174 Initialization Lists: Summary ...................................................................................................................... 174 Sorting Mail............................................................................................................................................... 174 Functors Compared with Function Pointers ................................................................................................ 175 Functors, Function Pointers, and Templates ............................................................................................... 175 Functors vs. Virtual Functions .................................................................................................................... 177

C++ WEB SERVER CONFIGURATION, CGI, POST, GET ................................................... 178 ************************************* ................................................................................................ 178 ************************************* ................................................................................................ 178 CGI Environment Variables ............................................................................................................................. 178 C++ CGI Library .............................................................................................................................................. 178 GET and POST Methods ................................................................................................................................. 178 Simple FORM Example: GET Method .............................................................................................................. 178 Passing Radio Button Data to CGI Program ..................................................................................................... 178 Passing Text Area Data to CGI Program ........................................................................................................... 178

Lambda Functions in C++11 - the Definitive Guide ..................................................................................... 180 Basic Lambda Syntax ................................................................................................................................. 181

Throw Specifications ...................................................................................................................................... 185 How are Lambda Closures Implemented? .................................................................................................. 185 Dangers and Benefits of Capture by Reference ........................................................................................... 186 Making Delegates with Lambdas ................................................................................................................ 187

Exceptions ..................................................................................................................................................... 190 Base and Derived Class Exceptions and inheritance .................................................................................... 193 Exam Question .......................................................................................................................................... 193 Dynamic exception specification ................................................................................................................ 195 exception specification .............................................................................................................................. 196

SHALLOW VS. DEEP COPYING ............................................................................................ 198 Shallow copying ............................................................................................................................................. 198 Deep copying ................................................................................................................................................. 198

PRIMITIVE DATA TYPES ...................................................................................................... 200

Page 6: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

6

TYPE CONVERSIONS ............................................................................................................. 201 Explicit ........................................................................................................................................................... 201

Implicit ...................................................................................................................................................... 201 Type-cast operator implicit ........................................................................................................................ 201 // implicit conversion of classes: ................................................................................................................ 201 Keyword explicit ........................................................................................................................................ 202

Type Cast operator explicit ............................................................................................................................. 202 reinterpret_cast ........................................................................................................................................ 203 const_cast ................................................................................................................................................. 203 typeid ....................................................................................................................................................... 203 static_cast ................................................................................................................................................. 204

STD::STRING - THE C++ STRING CLASS ........................................................................... 206 String concatenation ................................................................................................................................. 206 String Comparisons ................................................................................................................................... 206 String Length and Accessing Individual Elements........................................................................................ 207 Searching and Substrings ........................................................................................................................... 207 Modifying Strings via Splicing or Erasure .................................................................................................... 208 Copying vs. Sharing ................................................................................................................................... 209 Retrieving a c-style string (char*) ............................................................................................................... 209

OPERATOR OVERLOADING ................................................................................................. 210 Function overloading in C++: .......................................................................................................................... 216 Loops ............................................................................................................................................................. 217 do .................................................................................................................................................................. 217 for ................................................................................................................................................................. 218 while ............................................................................................................................................................. 220

INPUT/OUTPUT LIBRARY................................................................................................... 221 Stream-based I/O ........................................................................................................................................... 221

Detailed class definitions (all in namespace std) ......................................................................................... 221

C++ STANDARD LIBRARY HEADER FILES ....................................................................... 223 Algorithms ................................................................................................................................................ 223 Containers ................................................................................................................................................. 223 Input/Output............................................................................................................................................. 223 Iterators Library ......................................................................................................................................... 223 Other Utilities............................................................................................................................................ 223

Functor = function predicate .......................................................................................................................... 224

C++ OPERATOR PRECEDENCE............................................................................................ 226

MULTITHREAD, MULTI-THREAD, SEMAPHORE, LOCK, MUTEX, ETC SEE SEPARATE DOCUMENT ............................................................................................................................. 229

Socket ....................................................................................................................................................... 230 Header Files #include syntax .................................................................................................................. 231

#include................................................................................................................................................ 231 header files ........................................................................................................................................... 231

INPUT/OUTPUT WITH FILES ............................................................................................. 232 write to text file ......................................................................................................................................... 232 check if open ............................................................................................................................................. 233 close file .................................................................................................................................................... 233 read from text file ..................................................................................................................................... 233 reading an entire binary file ....................................................................................................................... 233

Page 7: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

7

PRACTICE PROGRAMS ......................................................................................................... 235 Priority Queue implentation with Array ..................................................................................................... 236

Stack Implementation with Class and Array .................................................................................................... 236 Queue Implentation with Class and Array ....................................................................................................... 237 Linked List Imp Class ptr to next Class ............................................................................................................. 239 Binary Trees in C++......................................................................................................................................... 242

Insert function........................................................................................................................................... 242 Delete function: Descend tree ................................................................................................................... 242

Binary Tree implemented in C++..................................................................................................................... 243 Header file ................................................................................................................................................ 243

(.cpp) ............................................................................................................................................................. 244 Main file used to test the tree.................................................................................................................... 249 Factorial Sum - Count # of trailing zero’s .................................................................................................... 252 code .......................................................................................................................................................... 252 Integer to English String Practice Problem Solution .................................................................................... 253 Decimal-to-Binary Conversion Challenge Solution ...................................................................................... 254 Linked List Reverse Printing Challenge........................................................................................................ 255 String Permutation Challenge .................................................................................................................... 255 File Size Challenge ..................................................................................................................................... 256 Line Count Challenge ................................................................................................................................. 257

List implemented as Array .............................................................................................................................. 259 declare ................................................................................................................................................. 259 size ....................................................................................................................................................... 259 find ....................................................................................................................................................... 259 assign one array to another ................................................................................................................... 259

Stack implemented as Array ........................................................................................................................... 260 declare ................................................................................................................................................. 260 Access and Modify ................................................................................................................................ 260 Add ...................................................................................................................................................... 260 Remove ................................................................................................................................................ 261

Stack implemented as Linked List ................................................................................................................... 262 Stack: using linked list. ............................................................................................................................... 262 Queue: java program to implement queue using linked list. ....................................................................... 263

Page 8: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

8

Classes, Templates - Summary declaration class x;

definition class x {};

initialization class x { T a = 0};

1) declaration declare it’s signature

class S; // declares S, a class prototype, no body

void xyz(double); // declares xyz, a function prototype, no body

int x;

“it exists somewhere”

2) definition definition of a previously declared name

class S { int a; int b; }; // defines S, S::a, and S::b

Blueprint for datatype(object), Doesn’t define any data, but defines what class consists of and what

operations can be performed on object of this class

A declaration is actually a definition if it contains extern specifier or static data in class definition or a

template parameter

Only one definition of any variable (Unique), function, class type, enumeration type, or template.

“it exists here, make memory for it” define memory heap stack

Also, can be both definition and declaration:

int x = 0;

3) Initialization

“assignment” of a value, at construction time.

T x = i; T x(i); T x {i}; int bar = 0; // variable int T::baz = 42; // static member variable

“here is the initial value for it”

Page 9: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

9

C++ Class Definitions:

When you define a class, you define a blueprint for a data type. This doesn’t actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.

A class definition starts with the keyword class followed by the class name; and the class body, enclosed by a pair of curly braces. A class definition must be followed either by a semicolon or a list of declarations. For example, we defined the Box data type using the keyword class as follows:

class Box { public: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box };

The keyword public determines the access attributes of the members of the class that follow it. A public member can be accessed from outside the class anywhere within the scope of the class object. You can also specify the members of a class as private or protected which we will discuss in a sub-section.

Define C++ Objects: A class provides the blueprints for objects, so basically an object is created from a class. We declare objects of a class with exactly the same sort of declaration that we declare variables of basic types. Following statements declare two objects of class Box:

Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box

Both of the objects Box1 and Box2 will have their own copy of data members.

note: subobject: Any object that is stored within another object (array elements, base class objects and data member objects).

Accessing the Data Members:

The public data members of objects of a class can be accessed using the

direct member access operator (.). Let us try the following example to make the things clear:

#include <iostream> using namespace std; class Box { public: double length; // Length of a box

Page 10: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

10

double breadth; // Breadth of a box double height; // Height of a box }; int main( ) { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 specification Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; // volume of box 1 volume = Box1.height * Box1.length * Box1.breadth;

cout << “Volume of Box1 : ”<< volume <<endl; // volume of box 2 volume = Box2.height * Box2.length * Box2.breadth;

cout << “Volume of Box2 : ”<< volume <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Volume of Box1 : 210 Volume of Box2 : 1560

It is important to note that private and protected members can not be

accessed directly using direct member access operator (.). We will learn how private and protected members can be accessed.

Page 11: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

11

Member Function 1. Sometimes called a method

2. member function of a class

3. function that has its definition or its prototype within the class definition like any other variable.

4. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.

5. defined within the class definition or

6. defined separately using scope resolution operator, ::.

7. A non-static member function is invoked on objects of the class it belongs to. It has implicitly access to the this pointer representing the current object. Through this pointer, it may access other members easily and with full access privileges (i.e. access private members).

Let us take previously defined class to access the members of the class using a member function instead of directly accessing them:

class Box { public: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box double getVolume(void);// Returns box volume }; class Box { public: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box // Member functions declaration double getVolume(void) // defined within the class definition { return length * breadth * height; } };

If you like you can define same function outside the class using scope resolution operator, :: as follows:

double Box::getVolume(void) // defined separately using scope

// resolution operator, ::

{ return length * breadth * height; }

Here, only important point is that you would have to use class name just before :: operator.

Page 12: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

12

A member function will be called using a dot operator (.) on a object where it will manipulate data related to that object only as follows:

Box myBox; // Create an object

myBox.getVolume(); // Call member function for the object

Let us put above concepts to set and get the value of different class members in a class:

#include <iostream> using namespace std; class Box { public: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box // Member functions declaration double getVolume(void); void setLength( double len ); void setBreadth( double bre ); void setHeight( double hei ); }; // Member functions definitions double Box::getVolume(void) { return length * breadth * height; } void Box::setLength( double len ) { length = len; } void Box::setBreadth( double bre ) { breadth = bre; } void Box::setHeight( double hei ) { height = hei; } // Main function for the program int main( ) { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // box 2 specification

Page 13: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

13

Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // volume of box 1 volume = Box1.getVolume();

cout << “Volume of Box1 : ”<< volume <<endl; // volume of box 2 volume = Box2.getVolume();

cout << “Volume of Box2 : ”<< volume <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Volume of Box1 : 210 Volume of Box2 : 1560

Page 14: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

14

Pointer to Member function

How to declare a pointer-to-member function

Return_Type (Class_Name::* pointer_name) (Argument_List);

Return_Type: member function return type.

Class_Name: name of the class in which the member function is declared.

pointer_name: a name we’d like to call the pointer variable

Argument_List: member function argument list.

ex declare pointer-to-member function

int (Foo::*fptr) (string);

To assign a member function to the pointer, the grammar is:

fptr= &Foo::f;

Of course declaration and initialization can be absorbed by one definition:

int (Foo::*fptr) (string) = &Foo::f;

Pointer-to-member function is not regular pointer

Pointer-to-member function doesn’t hold the “exact address” like a regular pointer does. We can imagine it holds the “relative address” of where the function is in the class layout. Let’s now demonstrate the difference. Pointer-to-member function represents the “offset” rather than an “absolute address”.

Pointer-to-member function different from “pointer-to-function”

ex

class Fred { int f(char a, float b); int (*)(char,float) //if an ordinary function int (Fred::*)(char,float) //if a non-static member function of class Fred int (Foo::*fptr) (string);

Note: if it’s a static member function of class Fred, its type is the same as if

it were an ordinary function: “int (*)(char,float)”.

Page 15: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

15

To invoke the member function through the pointer, we use the pointer-to-member selection operators, either

.* when the left-hand argument is a reference to an object,

->* when it is a pointer to an object.

ex void sample(Fred x, Fred& y, Fred* z, ) { x.*func(42); y.*func(42); z->*func(42);

.* when the left-hand argument is a reference to an object,

->* when it is a pointer to an object

note: static-member function are handled differently.

Page 16: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

16

Non Member Function Sometimes called a function

1. A non-member function has no implicit this.

2. only has access to public members

In the sample below, bar is a member function while freebar is not. Both do more or less the same, but note how bar gets an implicit object pointer via this.

class foo { public: void bar() { this->x = 0; // equivalent to x = 0; } int x; }; void freebar(foo* thefoo) { thefoo->x = 1; } // ... foo f; f.bar(); // f.x is now 0 freebar(&f); // f.x is now 1

C++ Class access modifiers

Data hiding is one of the important features of Object Oriented Programming which allows preventing the functions of a program to access directly the internal representation of a class type. The access restriction to the class members is specified by the labeled public, private, and protected sections within the class body. The keywords public, private, and protected are called access specifiers.

A class can have multiple public, protected, or private labeled sections. Each section remains in effect until either another section label or the closing right brace of the class body is seen. The default access for members and classes is private.

class Base { public: // public members go here protected: // protected members go here private:

Page 17: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

17

// private members go here };

The public members:

A public member is accessible from anywhere outside the class but within a program. You can set and get the value of public variables without any

member function as shown in the following example:

#include <iostream> using namespace std; class Line { public: double length; void setLength( double len ); double getLength( void ); }; // Member functions definitions double Line::getLength(void) { return length ; } void Line::setLength( double len ) { length = len; } // Main function for the program int main( ) { Line line; // set line length line.setLength(6.0);

cout << “Length of line : ” << line.getLength() <<endl; // set line length without member function line.length = 10.0; // OK: because length is public

cout << “Length of line : ”<< line.length <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Length of line : 6 Length of line : 10

The private members:

A private member variable or function cannot be accessed, or even viewed from outside the class. Only the class and friend functions can access

Page 18: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

18

private members.

By default all the members of a class would be private, for example in the following class width is a private member, which means until you label a member, it will be assumed a private member:

class Box { double width; public: double length; void setWidth( double wid ); double getWidth( void ); };

Practically, we define data in private section and related functions in public section so that they can be called from outside of the class as shown in the

following program.

#include <iostream> using namespace std; class Box { public: double length; void setWidth( double wid ); double getWidth( void ); private: double width; }; // Member functions definitions double Box::getWidth(void) { return width ; } void Box::setWidth( double wid ) { width = wid; } // Main function for the program int main( ) { Box box; // set box length without member function box.length = 10.0; // OK: because length is public

cout << “Length of box : ”<< box.length <<endl; // set box width without member function // box.width = 10.0; // Error: because width is private box.setWidth(10.0); // Use member function to set it.

cout << “Width of box : ” << box.getWidth() <<endl; return 0;

Page 19: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

19

}

When the above code is compiled and executed, it produces the following result:

Length of box : 10 Width of box : 10

The protected members:

A protected member variable or function is very similar to a private member

but it provided one additional benefit that they can be accessed in child classes which are called derived classes.

You will learn derived classes and inheritance in next chapter. For now you can check following example where I have derived one child class SmallBox from a parent class Box.

Following example is similar to above example and here width member will be accessible by any member function of its derived class SmallBox.

#include <iostream> using namespace std; class Box { protected: double width; //Base Protected variable }; class SmallBox:Box // SmallBox is the derived class. { public: void setSmallWidth( double wid ); double getSmallWidth( void ); }; // Member functions of child class double SmallBox::getSmallWidth(void) { return width ; } void SmallBox::setSmallWidth( double wid ) { width = wid; } // Main function for the program int main( ) { SmallBox box; // set box width using member function box.setSmallWidth(5.0);

cout << “Width of box :”<< box.getSmallWidth() << endl; return 0; } Output

Page 20: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

20

Width of box : 5

Initialize a variable Traditionally

int i = 10;

Constructor notation

int i(10);

Reference Variable

allows you create an alias (second name) for an already existing variable. A reference variable can be used to access (read/write) the original data.

int a; int& b = a; a = 10; Value of a is 10 and value of Reference(b) is 10 a changes then b changes, both point to same address

Whats the difference between a Reference Variable and a Pointer?

Pointers Reference Variables

Pointers can be assigned to NULL References cannot be assigned NULL. It should always be

associated with actual memory, not NULL.

Pointers can be (re)pointed to any object, at

any time, any number of times during the

execution.

Reference variables should be initialized with an object

when they are created and they cannot be reinitialized to

refer to another object

Pointer has own memory address and location

on stack

Reference variables has location on stack, but shares the

same memory location with the object it refer to.

Pa

Implicit Conversion/Coercion type A is used in a context where a compatible typeB is expected so that the type A will be promoted to type F.

short a = 2000 + 20; a will be promoted to int

add int to double, promoted to double

Page 21: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

21

C++ Class Constructor and Destructor

Constructor - create obj and initialize its values

ex

List X // declares object called X List X(); //function named X (returns a List)

Don’t call constructor explicitly

Dynamically allocate object

spreadsheetCell mycell(5);

spreadsheetCell[] *myCellp = new SpreadshhetCell (5) anotherCellp = new spreadsheetCell (4)

Stack Heap

Copy Constructor creates exact copy

Class SpreadsheetCell { Public: SpreadsheetCell (const spreadsheetCell &src); //copy all the fields from source object

// const = orig is not changed

// some_struct* a = new some_struct; // value-initialized // some_struct* b = new some_struct(); // zero-initialized

If you do not define these four methods (six in C++11) the compiler will generate them for you:

Default Constructor

Copy Constructor

Assignment Operator

Destructor

Move Constructor (C++11)

Move Assignment (C++11)

Default Constructor (If no other constructors are defined) construct base to member

call the base classes default constructor and

then each members default constructor (in the order they are declared)

Page 22: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

22

Destructor (If no destructor defined) tear down members to base

Calls the destructor of each member in reverse order of declaration.

Then calls the destructor of the base class.

Copy Constructor (If no copy constructor is defined)

Calls the base class copy constructor passing the src object.

Then calls the copy constructor of each member using the src objects members as the value to be copied.

Assignment Operator

Calls the base class assignment operator passing the src object.

Then calls the assignment operator on each member using the src object as the value to be copied.

Move Constructor (If no move constructor is defined)

Calls the base class move constructor passing the src object.

Then calls the move constructor of each member using the src objects members as the value to be moved.

Move Assignment Operator

Calls the base class move assignment operator passing the src object.

Then calls the move assignment operator on each member using the src object as the value to be copied.

note: either struct; or struct(); is valid

some_struct* a = new some_struct; // value-initialized some_struct* b = new some_struct(); // zero-initialized

zero initialized means all members will be initialized to zero, like int a; a will be initialized to 0

If you define a class like this:

declare struct of : class or struct struct some_struct: public some_base { std::string str1; int a; float b; char* c; std::string str2; };

What the compiler will build is:

struct some_struct: public some_base

Page 23: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

23

{ std::string str1; int a; float b; char* c; std::string str2; // Conceptually two different versions of the default constructor are built // One is for value-initialization the other for zero-initialization // The one used depends on how the object is declared. // some_struct* a = new some_struct; // value-initialized // some_struct* b = new some_struct(); // zero-initialized // some_struct c; // value-initialized // some_struct d = some_struct(); // zero-initialized // value-initialize version some_struct() : some_base() // value-initialize base (if compiler generated) , str1() // has a normal constructor so just call it // PODS not initialized , str2() {} // zero-initialize version some_struct() : some_base() // zero-initialize base (if compiler generated) , str1() // has a normal constructor so just call it. , a(0) , b(0) , c(0) // 0 is NULL , str2() // Initialize all padding to zero {} some_struct(some_struct const& copy) : some_base(copy) , str1(copy.str1) , a(copy.a) , b(copy.b) , c(copy.c) , str2(copy.str2) {} some_struct& operator=(some_struct const& copy) { some_base::operator=(copy); str1 = copy.str1; a = copy.a; b = copy.b; c = copy.c; str2 = copy.str2; return *this; } ~some_struct() {}

Page 24: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

24

// Note the below is pseudo code // Also note member destruction happens after user code. // In the compiler generated version the user code is empty : ~str2()

// PODs don’t have destructor , ~str1() , ~some_base(); // End of destructor here. // In C++11 we also have Move constructor and move assignment. some_struct(some_struct&& copy) // ^^^^ Notice the double && : some_base(std::move(copy)) , str1(std::move(copy.str1)) , a(std::move(copy.a)) , b(std::move(copy.b)) , c(std::move(copy.c)) , str2(std::move(copy.str2)) {} some_struct& operator=(some_struct&& copy) // ^^^^ Notice the double && { some_base::operator=(std::move(copy)); str1 = std::move(copy.str1); a = std::move(copy.a); b = std::move(copy.b); c = std::move(copy.c); str2 = std::move(copy.str2); return *this; } };

Constructors Empty, Copy, Char, Destructor #include <iostream> using namespace std; // __FUNCTION__ magic c++ variable that holds the name of the current function. class A { public:

A() { std::cerr << “Empty constructor” << std::endl; }

A(const A&) { std::cerr << “Copy constructor” << std::endl; }

A(const char* str) { std::cerr << “char constructor:” << str << std::endl;}

~A() { std::cerr << “destructor” << std::endl; } }; void direct() {

std::cerr << std::endl << “TEST:” << __FUNCTION__ << std::endl; A a(__FUNCTION__); } void assignment() {

std::cerr << std::endl << “TEST:” << __FUNCTION__ << std::endl; A a = A(__FUNCTION__); } void prove_copy_constructor_is_called()

Page 25: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

25

{

std::cerr << std::endl << “TEST:” << __FUNCTION__ << std::endl; A a(__FUNCTION__); A b = a; } int main() { direct(); assignment(); prove_copy_constructor_is_called(); return 0; }

Output TEST: direct char constructor: direct destructor TEST: assignment char constructor: assignment destructor TEST: prove_copy_constructor_is_called char constructor: prove_copy_constructor_is_called Copy constructor destructor destructor

Calling constructor without new create a new obj on stack

calls constructor of format Thing(const char*)

Thing myThing(“abcde”);

Create an object of type Thing using the constructor Thing(const char*)

Create an object of type Thing using the constructor Thing(const Thing&)

Call ~Thing() on the object created in step #1

Thing myThing = Thing (“abcde”);

The Class Constructor:

A class constructor is a special member function of a class that is executed whenever we create new objects of that class.

A constructor will have exact same name as the class and it does not have any return type at all, not even void. Constructors can be very useful for

Page 26: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

26

setting initial values for certain member variables.

Following example explains the concept of constructor:

#include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(); // This is the constructor private: double length; }; // Member functions definitions including constructor Line::Line(void) {

cout << “Object is being created” << endl; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length; } // Main function for the program int main( ) { Line line; // set line length line.setLength(6.0);

cout << “Length of line :” << line.getLength() <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Object is being created Length of line : 6

Parameterized Constructor:

A default constructor does not have any parameter, but if you need, a constructor can have parameters. This helps you to assign initial value to an object at the time of its creation as shown in the following example:

#include <iostream>

Page 27: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

27

using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(double len); // This is the constructor private: double length; }; // Member functions definitions including constructor Line::Line( double len) {

cout << “Object is being created, length =“ << len << endl; length = len; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length; } // Main function for the program int main( ) { Line line(10.0); // get initially set length.

cout <<“Length of line :” << line.getLength() <<endl; // set line length again line.setLength(6.0);

cout << “Length of line :” << line.getLength() <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Object is being created, length = 10 Length of line : 10 Length of line : 6

Using Initialization Lists to Initialize Fields:

In case of parameterized constructor, you can use following syntax to initialize the fields:

Line::Line( double len): length(len) {

cout << “Object is being created, length =” << len << endl; }

Above syntax is equal to the following syntax:

Page 28: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

28

Line::Line( double len) {

cout << “Object is being created, length =” << len << endl; length = len; }

If for a class C, you have multiple fields X, Y, Z, etc., to be initialized, then use

can use same syntax and separate the fields by comma as follows:

C::C( double a, double b, double c): X(a), Y(b), Z(c) { .... }

The Class Destructor: A destructor is a special member function of a class that is executed whenever an object of it’s class goes out of scope or whenever the delete expression is applied to a pointer to the object of that class.

A destructor will have exact same name as the class prefixed with a tilde (~) and it can neither return a value nor can it take any parameters. Destructor can be very useful for releasing resources before coming out of the program like closing files, releasing memories etc.

Following example explains the concept of destructor:

#include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(); // This is the constructor declaration ~Line(); // This is the destructor: declaration private: double length; }; // Member functions definitions including constructor Line::Line(void) {

cout << “Object is being created” << endl; } Line::~Line(void) {

cout << “Object is being deleted” << endl; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length;

Page 29: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

29

} // Main function for the program int main( ) { Line line; // set line length line.setLength(6.0);

cout << “Length of line :” << line.getLength() <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Object is being created Length of line : 6 Object is being deleted

Page 30: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

30

C++ Copy Constructor

Creates an object by initializing it with a previously created object of the same class, w

The copy constructor is used to:

Initialize one object from another of the same type.

Copy an object to pass it as an argument to a function.

Copy an object to return it from a function.

A copy constructor is a method that accepts an object of the same class and copies it’s data members to the object on the left part of assignement:

class Point2D{

int x; int y;

public int color;

protected bool pinned;

public Point2D() : x(0) , y(0) {} //default (no argument) constructor

public Point2D( const Point2D & ) ;

};

Point2D::Point2D( const Point2D & p )

{

this->x = p.x;

this->y = p.y;

this->color = p.color;

this->pinned = p.pinned;

}

main(){

Point2D MyPoint;

MyPoint.color = 345;

Point2D AnotherPoint = Point2D( MyPoint );

// now AnotherPoint has color = 345

If a copy constructor is not defined in a class, the compiler itself defines one.If the class has pointer variables and has some dynamic memory allocations, then it is a must to have a copy constructor. The most common form of copy constructor is shown here:

classname (const classname &obj) { // body of constructor }

Here, obj is a reference to an object that is being used to initialize another

object.

#include <iostream> using namespace std; class Line { public: int getLength( void ); Line( int len ); // simple constructor Line( const Line &obj); // copy constructor ~Line(); // destructor

Page 31: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

31

private: int *ptr; }; // Member functions definitions including constructor Line::Line(int len) {

cout << “Normal constructor allocating ptr” << endl; // allocate memory for the pointer; ptr = new int; *ptr = len; } Line::Line(const Line &obj) {

cout << “Copy constructor allocating ptr.” << endl; ptr = new int; *ptr = *obj.ptr; // copy the value } Line::~Line(void) {

cout << “Freeing memory!” << endl; delete ptr; } int Line::getLength( void ) { return *ptr; } void display(Line obj) {

cout << “Length of line :” << obj.getLength() <<endl; } // Main function for the program int main( ) { Line line(10); display(line); return 0; }

When the above code is compiled and executed, it produces the following result:

Normal constructor allocating ptr Copy constructor allocating ptr. Length of line : 10 Freeing memory! Freeing memory!

Let us see the same example but with a small change to create another object using existing object of the same type:

#include <iostream> using namespace std; class Line { public: int getLength( void );

Page 32: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

32

Line( int len ); // simple constructor Line( const Line &obj); // copy constructor ~Line(); // destructor private: int *ptr; }; // Member functions definitions including constructor Line::Line(int len) {

cout << “Normal constructor allocating ptr” << endl; // allocate memory for the pointer; ptr = new int; *ptr = len; } Line::Line(const Line &obj) {

cout << “Copy constructor allocating ptr.” << endl; ptr = new int; *ptr = *obj.ptr; // copy the value } Line::~Line(void) {

cout << “Freeing memory!” << endl; delete ptr; } int Line::getLength( void ) { return *ptr; } void display(Line obj) {

cout << “Length of line : ” << obj.getLength() <<endl; } // Main function for the program int main( ) { Line line1(10); Line line2 = line1; // This also calls copy constructor display(line1); display(line2); return 0; }

When the above code is compiled and executed, it produces the following result:

Normal constructor allocating ptr Copy constructor allocating ptr. Copy constructor allocating ptr. Length of line : 10 Freeing memory! Copy constructor allocating ptr. Length of line : 10 Freeing memory! Freeing memory!

Page 33: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

33

Freeing memory!

Delegation

This allows constructors to utilize another constructor’s behavior with a

minimum of added code.

constructor (. . .) : constructor (. . .) syntax

public: int max; int min; int middle; class_c(int my_max) { max = my_max > 0 ? my_max : 10; } class_c(int my_max, int my_min) : class_c(my_max) { min = my_min > 0 && my_min < max ? my_min : 1; } class_c(int my_max, int my_min, int my_middle) : class_c (my_max, my_min){ middle = my_middle < max && my_middle > min ? my_middle : 5; }

Page 34: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

34

Override and Final

Override

1- Prevents override with different parameters

2- Unexpected results

3- (actually = overloading)

Suppose the Derived::some_func is intended to replace the base class version. But instead, because it has a different signature, it creates a second virtual function. This is a common problem, particularly when a user goes to modify the base class.

C++11 provides syntax to solve this problem.

struct Base { virtual void some_func(float); }; struct Derived : Base { virtual void some_func(int) override;

// ill-formed - doesn’t override a base class method };

The override special identifier means that the compiler will check the base

class(es) to see if there is a virtual function with this exact signature. And if there is not, the compiler will indicate an error.

Final

1- prevent inheriting from classes

2- prevents derived classes from overriding it.

This is done with the special identifier final. For example:

struct Base1 final { }; //final on struct/class struct Derived1 : Base1 { }; // cannot derive base has been marked final

struct Base2 {

virtual void f() final; //final on function/method

}; struct Derived2 : Base2 { void f(); // cannot derive virtual function::f has been marked final };

Override and final That can be in the base class, or any derived class.

If it's in a derived classes you can use both the override and final specifiers.

Page 35: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

35

class B { public: virtual void f(int) {std::cout << "B::f" << std::endl;} }; class D : public B { public: virtual void f(int) override final {std::cout << "D::f" << std::endl;} }; class F : public D { public: virtual void f(int) override {std::cout << "F::f" << std::endl;} };

function declared as 'final' cannot be overridden by 'F::f'

Page 36: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

36

C++ Inline Functions commonly used with classes.

If a function is inline, the compiler places a copy of the code of that function at each point where the function is called at compile time.

Any change to an inline function could require all clients of the function to be recompiled because compiler would need to replace all the code once again otherwise it will continue with old functionality.

To inline a function, place the keyword inline before the function name and define the function before any calls are made to the function. The compiler can ignore the inline qualifier in case defined function is more than a line.

A function definition in a class definition is an inline function definition, even without the use of the inline specifier.

Following is an example, which makes use of inline function to return max of two numbers:

#include <iostream> using namespace std; inline int Max(int x, int y) { return (x > y)? x : y; } // Main function for the program int main( ) {

cout << “Max (20,10):” << Max(20,10) << endl; cout << “Max (0,200):” << Max(0,200) << endl; cout << “Max (100,1010):” << Max(100,1010) << endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Max (20,10): 20 Max (0,200): 200 Max (100,1010): 1010

C++ this Pointer

Every object in C++ has access to its own address through an important pointer called this pointer. The this pointer is an implicit parameter to all

member functions. Therefore, inside a member function, this may be used to refer to the invoking object.

Friend functions do not have a this pointer, because friends are not members of a class. Only member functions have a this pointer.

Let us try the following example to understand the concept of this pointer:

#include <iostream> using namespace std;

Page 37: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

37

class Box { public: // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) {

cout <<“Constructor called.” << endl; length = l; breadth = b; height = h; } double Volume() { return length * breadth * height; } int compare(Box box) { return this->Volume() > box.Volume(); } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; int main(void) { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 if(Box1.compare(Box2)) {

cout << “Box2 is smaller than Box1” <<endl; } else {

cout << “Box2 is equal to or larger than Box1” <<endl; } return 0; }

When the above code is compiled and executed, it produces the following result:

Constructor called. Constructor called. Box2 is equal to or larger than Box1

Page 38: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

38

Pointer to C++ classes

A pointer to a C++ class is done exactly the same way as a pointer to a structure and to access members of a pointer to a class you use the member access operator -> operator, just as you do with pointers to structures. Also as with all pointers, you must initialize the pointer before using it.

Let us try the following example to understand the concept of pointer to a class:

#include <iostream> using namespace std; class Box { public: // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) {

cout <<“Constructor called.” << endl; length = l; breadth = b; height = h; } double Volume() { return length * breadth * height; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; int main(void) { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 Box *ptrBox; // Declare pointer to a class. // Save the address of first object ptrBox = &Box1; // Now try to access a member using member access operator

cout << “Volume of Box1:” << ptrBox->Volume() << endl; // Save the address of first object ptrBox = &Box2; // Now try to access a member using member access operator

cout << “Volume of Box2:” << ptrBox->Volume() << endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Constructor called. Constructor called. Volume of Box1: 5.94 Volume of Box2: 102

Page 39: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

39

Unary operators overloading in C++

The unary operators operate on a single operand and following are the examples of Unary operators:

The increment (++) and decrement (--) operators. The unary minus (-) operator. The logical not (!) operator.

The unary operators operate on the object for which they were called and normally, this operator appears on the left side of the object, as in !obj, -obj, and ++obj but sometime they can be used as postfix as well like obj++ or obj--.

Following example explain how minus (-) operator can be overloaded for prefix as well as postfix usage.

#include <iostream> using namespace std; class Distance { private: int feet; // 0 to infinite int inches; // 0 to 12 public: // required constructors Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } // method to display distance void displayDistance() {

cout << “F:” << feet << “ I:” << inches <<endl; } // overloaded minus (-) operator Distance operator- () { feet = -feet; inches = -inches; return Distance(feet, inches); } }; int main() { Distance D1(11, 10), D2(-5, 11); -D1; // apply negation D1.displayDistance(); // display D1 -D2; // apply negation D2.displayDistance(); // display D2 return 0; }

When the above code is compiled and executed, it produces the following result:

F: -11 I:-10 F: 5 I:-11

Page 40: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

40

Friend functions

In principle, private and protected members of a class cannot be accessed from outside the same class in which they are declared. However, this rule does not apply to “friends”.

Friends are functions or classes declared with the friend keyword.

A friend function of a class is defined outside that class’ scope

right to access all private and protected members of the class.

Even though the prototypes for friend functions appear in the class definition,

friends are not member functions.

A friend can be

1) Friend of the class can be member of some other class.

2) Friend of one class can be friend of another class or all the classes in one program, such a friend is known as GLOBAL FRIEND.

3) Friend can access the private or protected members of the class in which they are declared to be friend, but they can use the members for a specific object.

4) Friends are non-members hence do not get “this” pointer.

5) Friends, can be friend of more than one class, hence they can be used for message passing between the classes.

6) Friend can be declared anywhere (in public, protected or private section) in the class.

function as a friend of a class,

precede the function prototype in the class definition with keyword friend as follows:

class Box { double width; public: double length; friend void printWidth( Box box ); function as a friend of a class void setWidth( double wid ); };

friend non-member function

access the private and protected members of a class

if it is declared a of that class. That is done by including a declaration of this external function within the class, and preceding it with the keyword friend:

Page 41: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

41

// friend functions #include <iostream> using namespace std;

class Rectangle { int width, height; public: Rectangle() {}

Rectangle (int x, int y) : width(x), height(y) {} int area() {return width * height;}

friend Rectangle duplicate (const Rectangle&);

friend non-member function

};

Rectangle duplicate (const Rectangle& param) { Rectangle res; res.width = param.width*2; res.height = param.height*2;

return res; }

int main () { Rectangle foo; Rectangle bar (2,3); foo = duplicate (bar);

cout << foo.area() << ‘\n’; return 0; }

OUTPUT 24

Can be friends of more than one class at a time.

Page 42: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

42

Friend classes

It is also possible to make an entire class a friend of another class. This gives all of the members of the friend class access to the private members of the other class. Here is an example:

class Storage { private: int m_nValue; double m_dValue; public: Storage(int nValue, double dValue) { m_nValue = nValue; m_dValue = dValue; } // Make the Display class a friend of Storage friend class Display; // Display can access any of Storage }; class Display { private: bool m_bDisplayIntFirst; public: Display(bool bDisplayIntFirst) { m_bDisplayIntFirst = bDisplayIntFirst; } void DisplayItem(Storage &cStorage) { if (m_bDisplayIntFirst)

std::cout << cStorage.m_nValue << “ ” << cStorage.m_dValue << std::endl; else // display double first

std::cout << cStorage.m_dValue << “ ” << cStorage.m_nValue << std::endl; } };

Because the Display class is a friend of Storage, any of Display’s members that use a Storage class object can access the private members of Storage directly. Here’s a simple program that shows the above classes in use:

int main() { Storage cStorage(5, 6.7); Display cDisplay(false); cDisplay.DisplayItem(cStorage); return 0; }

Output 6.7 5

A few additional notes on friend classes. First, even though Display is a friend of Storage, Display has no direct access to the *this pointer of Storage objects. Second, just because Display is a friend of Storage, that does not mean Storage is also a friend of Display. If you want two classes to be friends of each other, both must declare the other as a friend. Finally, if class A is a friend of B, and B is a friend of C, that does not mean A is a friend of C.

Page 43: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

43

Be careful when using friend functions and classes, because it allows the friend function or class to violate encapsulation. If the details of the class change, the details of the friend will also be forced to change. Consequently, limit your use of friend functions and classes to a minimum.

friend declaration The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.

Syntax

friend function-declaration (1)

friend function-definition (2)

friend elaborated-class-name ; (3)

friend simple-type-specifier ; friend typename-specifier ;

(4) (since C++11)

Description

Designates a function or several functions as friends of this class

class Y { int data; // private member

// the non-member function operator<< will have access to Y’s private members friend std::ostream& operator<<(std::ostream& out, const Y& o); friend char* X::foo(int); // members of other classes can be friends too friend X::X(char), X::~X(); // constructors and destructors can be friends }; // friend declaration does not declare a member function // this operator<< still needs to be defined, as a non-member std::ostream& operator<<(std::ostream& out, const Y& y) { return out << y.data; // can access private member Y::data }

(only allowed in non-local class definitions) Defines a non-member function,

and makes it a friend of this class at the same time. Such non-member function is always inline.

class X { int a; friend void friend_set(X& p, int i) { p.a = i; // this is a non-member function }

Page 44: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

44

public: void member_set(int i) { a = i; // this is a member function } };

Designates the class, struct, or union named by the elaborated-class-name as a friend of this class. This means that the friend’s member declarations and definitions can access private and protected members of this class and also that the nested classes of the friend can inherit from private and protected members of this class. The friend itself can also inherit from private and protected members of this class. (since C++11) If the name of the class that is used in the friend declaration is not yet declared, it is forward

declared on the spot.

Designates the type named by the simple-type-specifier or typename-specifier as a friend of this class if that type is a (possibly cv-qualified) class,

struct, or union; otherwise the friend declaration is ignored. This declaration

will not forward declare new type.

class Y {}; class A { int data; // private data member class B { }; // private nested type enum { a = 100 }; // private enumerator friend class X; // friend class forward declaration friend Y; // friend class declaration (since c++11) }; class X : A::B // Error until C++11: the base-clause is not part of member declarations // allowed in C++11 { A::B mx; // OK: A::B accessible to member of friend class Y : A::B { // OK: A::B accessible to base-clause of nested member of friend }; int v[A::a]; // OK: A::a accessible to member of friend };

Notes

Friendship is not transitive (a friend of your friend is not your friend)

Friendship is not inherited (your friend’s children are not your friends)

Prior to C++11, member declarations and definitions inside the nested class of the friend of class T cannot access the private and protected members of class T, but some compilers accept it even in pre-C++11 mode.

Storage class specifiers are not allowed in friend function declarations. A function that is defined in the friend declaration has external linkage, a function that was previously defined, keeps the linkage it was defined with.

Access specifiers have no effect on the meaning of friend declarations (they can appear in private: or in public: sections, with no difference)

A friend class declaration cannot define a new class (friend class X {}; is an error)

Page 45: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

45

When a local class declares an unqualified function or class as a friend, only functions and classes in the innermost non-class scope are looked up, not the global functions:

class F {}; int f(); int main() { extern int g(); class Local { // Local class in the main() function friend int f(); // Error, no such function declared in main() friend int g(); // OK, there is a declaration for g in main() friend class F; // friends a local F (defined later) friend class ::F; // friends the global F }; class F {}; // local F }

name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X, but is not accessible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided - see namespaces for details.

Page 46: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

46

Memory Structure

Stack and Heap

Heap

heap = dynamic (not automatic) new() and you have to delete. larger storage, free-store

use for

new/delete, STL containers, exceptions , Transient data objects

- Lifetime (scope) use heap If object should outlive parent

- smart pointers

during runtime, pgm needs to add memory. pointer = new type

pointer = new type (# of elements)

int *ptr = new vector<int>

foo = new int [5]

SomeClass* pToAnInstance = new SomeClass;

Stack automatic (ie destroyed automatically)

small, temp storage

grows and shrinks as data is added or deleted

only the pointer to the data is stored on the stack

use for

local vars (int x;) return addr, return value, funct args, compiler temps, interrupts

Stack frame for each local formal parm, vars, PDT, vars of object type

- Lifetime (scope) when method is finished, the stack frame is discarded.

recursion each invocation of method gets a separate stack frame. Thus each invocation has separate copy of formal parms, local vars, return value. primary cause of stack overflow

PC, Linux, Windows usually 1-8MB

embedded usually small

Page 47: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

47

Heap, Stack, Global, Static Variable Memory layout

When the data to be stored is larger than stack capacity, it typically gets written to the memory area allocated for global and static variables.

Determining worst-case maximum stack depth is useful in most embedded projects, as it allows you to allocate only as much RAM as needed for the stack while leaving the rest free for the developer to use in their application.

memcpy() vs memmove()

memcpy() doesn't take care of the overlapping source and destination whereas memmove() does.

choose memmove() when trying to copy 2 overlapped memory blocks.

Page 48: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

48

Storage Class Specifiers

Lifetime and Scope

Variable Lifetime, storage duration

Scope/Visibility linkage

auto automatic variable

local, block scope

No linkage

dynamic new to delete

extern static or thread storage

external access by other translation units.

heap new to delete whatever you assign the pointer to

local local block scope, stack

stack local, block scope

declaration until scope is exited

static (class) program runtime static or thread storage

access modifiers (private/protected/public)

internal access by all scopes in current translation unit(.cpp and .h)

static (global scope)

program runtime Namespace scope compilation unit it is instantiated in not stack or heap

thread_local thread storage - allocate when thread begins and deallocated when thread ends.

notes:

no linkage = only from scope it is in.

Translation unit - is a basic unit of compilation. Consists of contents of single source file, plus the contents of any header files included. Compiled into an executable program. ie file.cpp + h.

What kind of memory do you need? Auto ( Automatic Variables )

It really shines when working with templates and iterators:

vector<int> vec; auto itr = vec.iterator(); // instead of vector<int>::iterator itr

Page 49: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

49

Statics/Globals

use when you know you will always need it and you know that you don’t ever want to deallocate.

Embedded environments could be thought of as only have static memory

dynamic allocation works with variable lengths:

int len; cin>>len; int* array=new int[len]; //works fine

static doesn't:

int len; cin>>len; int array[len]; //doesn't work

Stack ( Stack Variables )

use when you know that as long as the function is in scope (on the stack) you want the variable to remain.

use when need variable in block of code and don’t need anywhere else in the program.

use as file resource that automatically goes away when you leave the code

Heap

Dynamic, new()

more flexible

if user clicks create box button and creates a new object, it may need to stick around long after the function is exited, so it can’t be on the stack.

Dramatically slower to allocate

Forget to free memory is a memory leak, use garbage collector and it also slows system down.

Heap memory overflows also can have significant an impact on system behavior, and can be notoriously difficult to debug.

heap vs stack void sumFunction() // on the stack { SomeClass anInstance; // On the stack as automatic variable SomeClass* pToAnInstance = new SomeClass; // On the heap eventhough in function allocated on stack

If the object is in heap-allocated memory, then its sub-objects are there too, and if the object is on the stack, then its sub-objects are there too, because they

Page 50: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

50

always occupy the same memory, they are one and the same.

Polymorphism doesn’t require heap allocation. Derived x;Base * y=&x;

In addition to stack and heap there are static and thread allocation.

C++ standard doesn't really talk about "heap" and "stack". Implementation details of compiler/platform.

Use smart pointers for exception safe code,

They're important to consider when optimizing or generally thinking about performance, but they're mostly irrelevant from a program-functionality point of view.

Java or C# is reference-semantic languages the stack doesn’t exist (abstracted

away). All memory is managed by virtual machine, basically all heap-allocated

memory.

Automatic

auto specifier

auto variable

auto function

auto function return type

declaretype(auto)

auto::

Mixing auto variables and functions in one declaration, as in auto f() -> int, i = 0; is not allowed. template<class T, class U>

auto add(T t, U u) -> decltype(t + u) // the return type is the type of

operator+(T,U)

{

return t + u;

}

auto a = 1 + 2;

std::cout << "type of a: " << typeid(a).name() << '\n';

auto b = add(1, 1.2);

std::cout << "type of b: " << typeid(b).name() << '\n';

//auto int c; //compile-time error

auto d = {1, 2};

std::cout << "type of d: " << typeid(d).name() << '\n';

Page 51: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

51

x86 Architecture

CISC - Complex instruction Set Computer architecture.

Microsoft Win32 uses x86 processor in 32-bit flat mode

Function parameters are passed on the stack, pushed right to left, and the callee cleans the stack.

Unprivileged integer registers

eax Accumulator receives function return values

ebx Base register

ecx Count register

edx Double-precision register

esi Source index register

edi Destination index register

ebp Base pointer register

esp Stack pointer

eip Instruction pointer

flags flags

flags

of Overflow

if Interrupt

pf Parity

many more

Page 52: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

52

PROCESSOR'S STACK FRAME LAYOUT

Implicit, Stack frame constructed during the function call for memory allocation.

Explicit, memory allocation can be requested from and released to heap area using malloc(), calloc(), realloc(), new, free() and delete respectively.

A typical layout of a stack frame is shown below although it may be organized differently in different operating systems:

Function parameters. Function’s return address. Frame pointer. Exception Handler frame. Locally declared variables. Buffer. Callee save registers.

And the arrangement in the stack can be illustrated as shown below.

Figure 1: Typical illustration of a stack layout during the function call.

From the layout, it is clear that a buffer overflow if occurs, has the opportunity to overwrite other variables allocated at the memory address higher than the buffer that is the locally declared variables, the exception handler frame, the frame pointer, the return address, and the function parameters.

CPU registers

ESP (Extended Stack Pointer) holds the top stack address

EBP (Extended Base Pointer) points to stack bottom, fixed address

FP a stack frame pointer holds an address that point to a fixed location within a frame.

local variables could be referenced by giving their offsets from ESP.

Page 53: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

53

Abstract Data Type (ADT)

ADT -> Data Struct -> Implementation

ADT is Data Abstraction, Concept, Logical representation of Data Structure

Data storage and operations are encapsulated by an ADT

ADT is a interface

Data Structure (data type ie possible data values) + Set of Operations on these values

Unconcerned / Independent of implementation

ADT examples Containers classes (vector, string, queue, stack, deque, sets, maps, etc) collections tree table graph

Page 54: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

54

Data Structures

1. Tells how to store collection of objects in memory, concrete and

2. what operations can be performed (using interfaces)

3. use Algorithms for operations

4. definitions are often extended to include BOTH concrete AND logical descriptions of complex data types ( ADTs + Data Structures together)

5. An ADT is explicitly abstract, a data structure is a more general term that can be totally abstract, or refer to implementation details as well.

Big-O Taxonomy

Growth Rate

Name Notes

O(1) constant Best, independent of input size

O(log, log n)

very fast

O(log n) logarithmic tree-based data structs

O(n) linear Have to look at all data

O(n log n)

Time to sort

O(n2) quadratic Ok if n is small

C++ Data Structure = Container

Containers Vector String Array Deque List Map Multimap (very common ADT Dictionary) Sets Stack Implement with Class and Array queue Implement with Class and Array Priority Queue IImplement with Class and Array

Page 55: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

55

ADT/Data Structure Implementation

In C++ we use Classes for implementation and when possible use STL’s

Interface (*.h):

Class Definition

Prototypes for the operations (interface)

data members for the actual (concrete) representation

Implementation (*.cpp)

function definitions for th eoperations

depends on rep of data memebers, their concrete implementatoin

Operations

Access Function

non-mutable, non-destructive

Modification function

mutable, destructive

Algorithm

Procedure for solving problems

Data Structure Organization

Group Data Structures Sequential Linear

Restricted Access Stack, Queue, Deque Unrestricted Access List, Array, File

Non-Linear

Tree Graph

Lists Doubly Linked list Array list Linked list

Tree’s Binar, Red/Black, binary search tree, binary tree B-Tree’s B-Tree Heaps Heap Symbol Table

Page 56: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

56

ADT / Data Structure doesn’t care about the implementation

Arraylist = implmentation of list based on arrays

LineList = implmentation of list based on nodes

Set, Map, Stack, Queue = implementation of List

ex

Implementing a stack ADT in C++ Classes force data abstraction

Stack of int ADT, use two files, .h (header) and .cc (implementation) // The header file, intstack.h class IntStack { public: IntStack(); // A constructor for this class. void push(int x); // The operations of the Stack ADT. int pop(); void makeEmpty(); bool isEmpty(); private: int data[100]; // Contains the items on the stack. int top; // Number of items on the stack. }; // The file intstack.cc #include "intstack.h" IntStack::IntStack() { top = 0; // A stack is empty when it is first created. } void IntStack::push(int x) { if (top == 100) // ERROR; throw an exception. throw "Attempt to push onto a full stack"; data[top] = x; top++; } int IntStack::pop() { if (top == 0) // ERROR; throw an exception throw "Attempt to pop from an empty stack"; top--; return data[top]; } void IntStack::makeEmpty() { top = 0; } bool IntStack::isEmpty() { return (top == 0); }

Implementing a stack ADT in C++ with STL

ex #include <stack> //stack<BaseType>

Page 57: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

57

stack<int> nums; stack<string> words; // operations available s.pop() s.top() s.empty() ex 2 #include <queue>…

Any Data Type Can Be Compared:

By overloading the < operator, we can define an order on any type(e.g. MyType)

We can sort a vector of MyTypes via: struct MyType { string name; // ... }; bool operator<(const MyType & A, const MyType & B) { return A.name < B.name; } vector<MyType> vec; // ...fill in vec with many MyType records... sort(vec.begin(), vec.end());

Thus, we can assume we can compare any types.

Page 58: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

58

How to choose the right Data Structure? Match Characteristics.

Do you need random access?

Do you perform a lot of insertions?

A lot of searching?

allow duplicate?

Ordered?

Traverse elements?

size of data set?

Array - 1st choice

small # elements = fast

random access

unordered

fast insertion

slow traverse

ordered array

fast search

fast insertion

Linked List - 2nd choice

dynamic growth - don’t know size

unordered

insertion = constant time (beginning of list)

deletion - faster than array (NO items shifted)

search slow - linear, binary search not possible, only access from first node

Binary Tree’s 3rd choice

search insert, delete fast operation

iterator for max min values

traversal in order

must keep balanced though

random order use red-black tree

Hash table - 4th choice

fast if small table

Page 59: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

59

sort unavailable

traversal not possible

faster than trees, degrades fast if large table

based on array

rough idea of # elements req

Page 60: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

60

ADT Average Execution Time

Abstract Data Type Access by index

Search

Insert

Delete Use when…

Array (T[])

O(1) FAST

O(N) O(N) O(N) fixed # elements, acccess thru index

Linked list (LinkedList<T>) no

O(N) O(N) O(1) O(N) rarely used due to dynamic arrays = List (List<T>),

Dynamic array (List<T>)

O(1) O(N) O(1) O(N)

you have to add elements quickly and access thrm thru index faster and easier to use than linked list, AKA array list, resizable array

Stack (Stack<T>)

slow O(1) O(1) need to implement LIFO

Queue (Queue<T>)

O(1) O(1) need to implement FIFO

hash-table used to implement Dictionary (Dictionary<K, T>)

O(1) O(1) O(1) add and search by key very fast if key is known

hash-table used to implement Set (HashSet<T>)

O(1) O(1) O(1) ditto

Heap fast fast fast access largest item slow access to other items

Binary Tree fast fast fast if remains balanced deletion algorithm is complex

Red-Black Tree fast fast fast complex to implement

balanced search tree (BST) used to implement Dictionary (SortedDictionary<K, T>)

O(log(N))

O(log(N))

O(log(N))

balanced search tree (BST) used to implement Set (SortedSet<T>)

O(log(N))

O(log(N))

O(log(N))

O(1) - Constant,fast, number of steps doesn’t depend on size of input

O(N) - Linear, Slow, It takes about the same amount of steps as the number of

elements

O(log(N)) - Logrithmic , ex N = 1M elements = 20 steps

O(N2) - Quadratic, ex N=100 takes about 10,000 steps

Page 61: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

61

Average and Worst Execution Times

O(n log n) faster than O(n2)

Page 62: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

62

Data Structures implemented as Array

Array

List interface (operations) - Implemented as Array

C++ array doesn’t keep track of its length, but in these examples “array” class/template keeps track of its length

declare

size

find

assign one array to another

Page 63: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

63

Stack implemented as Array Stack implements the list interface using an array

Real Life Examples

undo\redo operation in word processors

Java Virtual Machine (JVM) stack oriented

Arighmetic expression - Postfix Expression

memory stack

reversing data like a list

parsing

declare

Access and Modify

Add

Page 64: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

64

Remove

Page 65: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

65

Queue implemented as Array List implements the list interface using an array

Real Life Example

Transport and operations research stored until used later.

Real Life Example Priority Queue

process scheduling in CPU

Declare

Add

Remove

Resize since it is an array

Page 66: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

66

Implement Deque as Array ArrayQueue: sequence, efficently add to one end of the sequence and remove from the other end.

ArrayDeque: efficently add and remove from both ends.

List implements the list interface using an array

Declare

Get, Set

Page 67: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

67

Implement Data Structures as Linked List section

Singly Linked List

List

Interface

easily acts as Queue, Stack or Deque Interface

size()

get(i)

set(I,x) set falue of I to x

add(I,x) add x at position i

remove(i)

Implementation

Can be implemented as Array (List interface) or Linked List

Implementation

head and tail

Add(x) at tail though

Page 68: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

68

Remove at head like pop

Push(x) easily implement stack with push and pop

Pop easily implement stack with push and pop

Page 69: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

69

example

Linked_List_Imp_Class_ptr_to_next_Class

Print Linked List Elements in Reverse order

straightforward implementation, No recursion used.

While(Head != NULL){ if(internalNode == NULL){ internalNode = Head – > next; } else{ internalNode = internalTempNode; } internalTempNode = internalNode -> next; if(internalTempNode == NULL){ release(temp1); } Head->next = prev; prev = Head; prev->next = Head->next; Head = internalNode; if(internalNode == NULL){ head = prev; }

Page 70: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

70

Implement Data Structures as Sets section

Sets

Interface

size()

add(x)

remove(x)

find(x)

Implentation

Hash Tables

Use - store small number of intergers (integer could be associated with data item) from a large range.

Associate data with keys that maybe integers, strings, objects, arrays, ADT’s.

Chained Hash Table for integer keys OK.

Non-integer keys map to w-bit hash codes. Hash code more complex. Reference Data Structures, C++ implentation pdf.

List Interface - implementation as array ro Singly Linked List

List implements the list interface using an array

Real Life Examples

symbol table for compilers

database indexing

caches

Chained Hash Table Implementation of Set interface

hashing with chaining to store data as a array of lists.

Integer keeps trace of

total number of items in all listsUse hashing with chaining to store data as an array of lists

Page 71: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

71

Define Hash Table

Add

append to list

Remove

Page 72: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

72

Find

Page 73: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

73

Binary Trees

One of most fundamental structures in computer science.

storing sorted data and rapidly retrieving stored data

Hierarchical (no linear)

Real Life Examples

Data base designing : creating your own database just to store the data based upon some key value

Creating file system : Operating systems maintain a disk’s file system as a tree.

Zoology: Maintaining the structures of the entire animal & plant kingdom.

Social Networks : Establishing relations between users based on some key.

Make information easy to see

Manipulate sorted lists

Router algorithms

B-Trees (Binary Trees):

Interface

Implementation

E-commerce : while accessing unique keys. B-Trees balanced multi-way search tree of order N.

Searching : Searching quickly for a given element.

Only two children nodes per parent node

data structure for rapidly storing sorted data and rapidly retrieving stored data.

parent nodes / leaves, each of which stores data and also links to up to two other child nodes (leaves)

Leaves left to right become greater in value

Each leaf connects to two other leaves

easily access and insert data in a binary tree using search and insert functions recursively called on successive leaves.

10

/ \

6 14

/ \ / \

5 8 11 18

Pseudocode of insert function

Pseudocode of Delete function: Descend Tree

Binary_Tree_implementation

Tree_header

Tree_cpp_file

Tree_test

Page 74: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

74

Binary Tree Search (BST)

Interface

Implentation

Binary Search Tree

each node every descendant node’s value in the left subtree is less than value of parent node and every decendant node’s value in the right subtree is greater than value of parent.

fastest for using searches

preorder traversal - current node, visit left child, then right child

inorder traversal - visit left child, then current node, then right child

postorder traversal - left child, right child, current node

Leaf node - no children

Root - no parent

Implementation #1

represent a node

pointer to root

compute depth of node

Page 75: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

75

recursive algorithms to computer size of tree, height

traverse Binary Tree with recursion

traverse Binary Tree without recursion

Page 76: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

76

Binary Tree implementation #2

struct tnode

{

int data;

struct tnode *left;

struct tnode *right;

};

typedef struct tnode TreeNode;

TreeNode *newItem(int data)

{

TreeNode *pn = (TreeNode *) malloc(sizeof(TreeNode));

pn->data = data;

pn->left = 0;

pn->right = 0;

return pn;

}

TreeNode* insertTree(TreeNode *pn, int data)

{

if (!pn)

return newItem(data);

else

{

if (data <= pn->data)

pn->left = insertTree(pn->left, data);

Page 77: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

77

else

pn->right = insertTree(pn->right, data);

}

return pn;

}

TreeNode *createTree()

{

TreeNode * pr = insertTree(0, 4);

insertTree(pr, 1);

insertTree(pr, 2);

insertTree(pr, 3);

insertTree(pr, 5);

insertTree(pr, 6);

return pr;

}

void printPreorder(TreeNode *pn)

{

if (pn)

{

printf(“preorder = %d\n”, pn->data);

printPreorder(pn->left);

printPreorder(pn->right);

}

}

void printPostorder(TreeNode *pn)

{

if (pn)

{

printPostorder(pn->left);

printPostorder(pn->right);

printf(“postorder = %d\n”, pn->data);

}

}

void printInorder(TreeNode *pn)

{

if (pn)

{

printInorder(pn->left);

printf(“inorder = %d\n”, pn->data);

printInorder(pn->right);

}

}

int size(TreeNode *pn)

{

if (pn)

Page 78: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

78

return 1 + size(pn->left) + size(pn->right);

else

return 0;

}

int depth(TreeNode *pn)

{

if (pn)

{

int ld = depth(pn->left);

int rd = depth(pn->right);

if (ld > rd)

return ld + 1;

else

return rd + 1;

}

else

return 0;

}

int minVal(TreeNode *pn)

{

if (pn)

{

while(pn->left)

pn = pn->left;

return pn->data;

}

else

return 0;

}

int maxVal(TreeNode *pn)

{

if(pn)

{

while(pn->right)

pn = pn->right;

return pn->data;

}

else

return 0;

}

How to print all Tree nodes at at given level say at a Level order tree traversal (2 methods)

1) Print all nodes at a given level (printGivenLevel) /* implementation

Page 79: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

79

A binary tree node has data, pointer to left child and a pointer to right child*/ struct node { int data; struct node* left; struct node* right; };

/*Function to print level order traversal of tree*/

printLevelorder(tree)

for d = 1 to height(tree)

printGivenLevel(tree, d);

2) print level order traversal of the tree (printLevelorder).

for each node, first the node is visited and then it’s child nodes are pu in a FIFO queue

/* implementation queue is implemented using an array, could used linked list as well */ printLevelorder(tree) 1) Create an empty queue q 2) temp_node = root /*start from root*/ 3) Loop while temp_node is not NULL a) print temp_node->data.

b) Enqueue temp_node’s children (first left then right children) to q

c) Dequeue a node from q and assign it’s value to temp_node

6. Level order tree traversal (2 methods)

Print all nodes at a given level (printGivenLevel) /* implementation

A binary tree node has data, pointer to left child and a pointer to

right child*/

struct node

{

int data;

struct node* left;

struct node* right;

};

/*Function to print level order traversal of tree*/

printLevelorder(tree)

for d = 1 to height(tree)

printGivenLevel(tree, d);

Red-Black binary search tree Widely used C++ STL Quick search, but implementation complexity

Page 80: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

80

Page 81: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

81

Heaps binary tree Priority Queue data structure implementated by heap (special kind of binary tree)

partially sorted binary tree

heap uses an array to simulate a binary tree. Very fast sorting algorithms named heapsort

implement represent binary tree as array.

Heap

Interface

Implementation

Min Max

Maximum priority for task

Student with least or max points on exam

Highest priority patient in hospital

Shortest distance route between work location and front door

heapsort for sorting

heapsort usually slower than quicksort, but guarantees O(nlogn) worst case scenario

whereas quicksort worst case is quadratic.

Implentation

Page 82: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

82

elements are stored in an array

Add

swap with parent until no longer smaller than its parent

Page 83: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

83

Remove

removes smallest value from heap

Page 84: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

84

Sorting Algorithms

Merge-sort Quick-sort Heap-sort They take an input array and sort elements into non-decreasing order Comparison-based.

Don’t care about type of data sorted

Merge-sort recursive divide and conquer recursively sort array 1 and sort array 2 then merge the two arrays

Implementation

Merge

Page 85: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

85

Quicksort Divide and conquer algorithm Merge-sort merges after sorting arrays Quick-sort does all work at once, in place

Implementation

Page 86: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

86

Heap-sort inplace sorting algorithm uses binary heaps converts the input array into a heap then repeatedly extracts the minimum value

Implementation

Page 87: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

87

Standard Template Library

Standard Template Library is a set of well structured Generic ADT’s 2 categories

1. Container Library Generic collection of class templates to easily implement common data

structures like queue, lists and stacks

Manages storage allocated for elements

Provides member functions to access these elements

directly or

thru iterator

2 categories

Sequence containers

Associative containers

2. Iterator Library Behave like pointers

mechanism for accessing elements in a container the iterator is associated with

3. Algorithm Library

STL’s doesn’t guarantee what data structures are used for implementation!!

Containers

only knows about iterators

Interators

Algorithms

only knows about iterators

Page 88: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

88

Summary of ADT, Data Structure, Interface and Implementation ADT ADT = Data Structure + set of operations

ADT Interface required Client expects these interfaces available and concentrates on their usage Creators, Producers = makes new values Mutators: change the value Observers: view value

Data Structure operations available Programmer uses Data Structure operations to verify interface covered. Reference STL chart below of operations available.

ADT/Data Structure Implementation using Construct a Class with Methods or use C++ STL templates already available or use Java Collections API ADT Implementation is isolated from client

Binary Search Tree (BST)

a ADT and Data Structure

Vector

Deque empty erase max_size pop_back pop_front push_back push_front resize

empty erase max_size pop_back pop_front push_back push_front resize

template <class T> class deque; Vector does everything deque does except push_front pop_front

Dictionary binary search tree (BST) hashtable Ordered array unordered array

Graph List List interface

FIFO addFirst(x) removeFirst() LIFO addLast removeLast

Doubly-linked list array Deque

Map-sorted binary search tree red-black tree (binary search tree)

Map-unsorted

hash map = unordered map binary search tree

C++ STL Java has hash functions hash table faster than red-black tree (binary search tree)

Queue Queue interface FIFO addFirst(x) = add(0,x) removeFirst = remove(0) LIFO enqueue(), addLast(x)= add(size(),x) dequeue(), removeLast() = remove(size()-1) additional Needs isEmpty() isFull()

array Singly Linked List (FIFO)

Queue (Priority Queue)

Stack LIFO array,

Page 89: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

89

push() pop() additional needs size() isEmpty() top() create()? destroy()?

vector Singly Linked List, Deque=Adapter Pattern. template <class T> class Stack

Table Tree insert

delete find size traverse inorder traverse post-order traverse pre-order traverse level-order

Tree is a ADT and Data Structure because specialized trees are Data Structures like heap for ex

heap implimented as array in C++

Set-sorted binary search tree red-black tree (binary search tree)

Set-unsorted

binary search tree hash table

C++ STL Java has hash functions hash table faster than red-black tree (binary search tree)

Set-sorted List interface

FIFO Queue AND LIFO Queue (stack) addFirst(x) removeFirst() addFirst(x) removeFirst()

Deque Doubly-linked list as array

Vector

size, clear, empty, push_back, pop_back, back, front iterator begin, end

STL vector

Adapter pattern = Implement a class by using the methods of another class

Sequence containers Headers <array> <vector> <deque> <list>

Members array vector deque list

constructor implicit vector deque list

destructor implicit ~vector ~deque ~list

operator= implicit operator= operator= operator=

iterators

begin begin begin begin begin

end end end end end

rbegin rbegin rbegin rbegin rbegin

rend rend rend rend rend

capacity

size size size size size

max_size max_size max_size max_size max_size

empty empty empty empty empty

element access

front front front front front

back back back back back

insert

insert insert insert

Page 91: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

91

Page 92: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

92

Page 93: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

93

Page 94: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

94

Container class templates

sequences of data, collection of elements in a data structure

Outline summary

1. Sequential Containers- Linear 1. array 2. vector 3. deque 4. forward_list 5. list

Sequential access in array, vector, deque, forward_list, list

Direct access in deque and vector

2. Associative Containers - Based on a tree 1. set 2. multiset 3. map 4. multimap

3. Unordered Associative Containers - 1. unordered_set 2. unordered_multiset 3. unordered_map 4. unordered_multimap

4. Container Adapters special predefined containers, implemented by using fundamental container classes. Meet special needs. 1. stack 2. queue 3. priority_queue

Every container has

1. iterator 2. const_iterator

Page 95: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

95

1. Container Sequential Arrange the data they contain in a linear manner, ie not a tree. Similar to arrays but not req stored contiguously.

Implement Data Structure Array as an array, vector or deque.

1. array

Traverse using index a[n] or pointer *p

Two ways for traversing an array

Using an index:

T* a = new T[size]; for (int n=0;n<size;++n) cout << a[n];

Using pointers:

for (T* p = a; p !=a+size; ++p) cout << *p;

2. vector

index starts at 0 (zero), vector+offset, vector + 0 = first element, same as array[0]….

open ended, array capable of growing as needed to contain its elements,

it is random access and

contiguously stored, and

length is highly flexible.

For these reasons and more, vector is the preferred sequence container for most applications.

Vector specific operations

Changing the size

void resize(size_type) void reserve(size_type) size_type capacity()

Note:

reserve and capacity regard memory allocated for vector!

resize and size regard memory currently used for vector data

Assignments

container = c … copy of container c container.assign(n) …assign n elements the default value container.assign(n,x) … assign n elements the value x container.assign(first,last) … assign values from the range [first,last[

Note:

assignment does not allocate, do a resize before!

Page 96: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

96

For list and deque (stack, queue)

container.push_first(T x) // insert element at start

container.pop_first() // remove first element

3. deque

(pronounced “deck”) is a double-ended queue class,

implemented as a dynamic array that can grow from both ends.

allows for fast insertions and deletions at the beginning and end of the container.

It shares the random-access and flexible-length advantages of vector,

but is not contiguous.

implement queues, FIFO, add to one end, delete from the other

4. forward_list

5. list

Lists only provide access to the start and end of the list

Linked List can be implemented as list

traverse linked list template <class T> struct node

{

T value; // the element node<T>* next; // the next Node }; template<class T> struct list

{ node<T>* first; }; list<T> l; … for (mode<T>* p=l.first; p!=0; p=p->next) cout << p->value;

no random access provided.

fast insertion and removal

doubly linked list that enables bidirectional access, fast insertions, and fast deletions anywhere in the container

doubly linked list where each element in the container contains pointers that point at the next and previous elements in the list.

list -specific functions splice - joins lists without copying, moves elements from one to end of the other

sort - optimized sort, just relinks the list without copying elements

merge - preserves order when “splicing” sorted lists

remove(T x), remove_if(criterion) -

example:

Page 97: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

97

bool is_negative(const T& x) { return x<0;}

can be used like

list.remove_if(is_negative);

Sequential Constructors

A sequence is a linear container

container() … empty container container(n) … n elements with default value container(n,x) … n elements with value x container(c) … copy of container c container(first,last) … first and last are iterators container with elements from the range [first,last[

Example: std::list<double> l; // fill the list … // copy list to a vector std::vector<double> v(l.begin(),l.end());

Inserting and erasing anywhere in a sequence List operations (slow for vectors, deque etc.!)

insert (p,x) // insert x before p insert(p,n,x) // insert n copies of x before p insert(p,first,last) // insert [first,last[ before p erase(p) // erase element at p erase(first,last) // erase range[first,last[ clear() // erase all

For all sequences: inserting/removing at end

container.push_back(T x) // add another element at end container.pop_back() // remove last element

Page 98: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

98

2. Container Associative Tree Data Structure can be implement as map, set, multimap, multiset

set

no dups,

Value of elements cannot be modified *it=10; not allowed

Always sorted

Template < Class T, set::key_type Class compare = less <T> Class Alloc = allocator<T> > class set; set<int> myset; myset.insert(3); myset.insert (1); myset.insert(7); //inserted out of order, but stored in order {1,3,7}

multiset

dups ok.

Value of elements cannot be modified

Always sorted

map

Key Value

Pair

also called an associative array

Unique Key

is a set where each element is a pair, called a key/value pair.

The key is used for sorting and indexing the data, and must be unique. The value is the actual data.

Value of elements cannot be modified

Page 99: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

99

Implemented as a tree of pairs

Access value directly with correxponding key using (operator[])

Std::map template < class Key, // map::key_type class T, // map::mapped_type class Compare = less<Key>, // map::key_compare class Alloc = allocator<pair<const Key,T> > // map::allocator_type > class map;

Insert key and value

mymap.insert(pair<char,int>(‘a’,100)); or

insert makepair(‘z’,200)); or

mymap.insert(it, pair<char,int>(‘a’,100)); “it” is a hint to compiler of parameter type

print key and value

for (it=mymap.begin(); it!=mymap.end(); it++)

cout << (*it).first << “ ->” << (*it).second << endl;

Searches

Fast (log N) a.find(k), a.count(k), a.lower_bound, a.upper_bound,

Search example in a tree

Look for all my phone numbers:

// some typedefs

typedef multimap<std::string, int> phonebook_t;

typedef phonebook_t::const_iterator IT;

typedef phonebook_t::value_type value_type;

// the phonebook

phonebook_t phonebook;

// fill the phonebook

phonebook.insert(value_type(“Troyer”,32589)); …

// search all my phone numbers

pair< IT,IT> range = phonebook.equal_range(“Troyer”); // print all my phone numbers

for (IT it=range.first; it != range. second;++it)

cout << it->second << “\n”;

multimap

also called a dictionary

dups ok

Page 100: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

100

Real-life dictionaries are multimaps: the key is the word, and the value is the meaning of the word.

All the keys are sorted in ascending order, and you can look up the value by key.

Some words can have multiple meanings, which is why the dictionary is a multimap rather than a map.

Value cannot be changed

Dictionary Implementation languages awk: D[“AAPL”] = 130 # associative array perl: my %D; $D[“AAPL”] = 130; # hash python: D = {}; D[“AAPL”] = 130 # dictionary C++: map<string,string> D = new map<string, string>(); D[“AAPL”] = 130 // map

Unordered associative containers Unordered associative containers implement unsorted (hashed) data structures that can be quickly searched (O(1) amortized, O(n) worst-case complexity).

ex place elements in unordered assoc container

unordered_set<string> myset = {“red”, “green”, “blue”};

unordered_set<string>::const_iterator itr = myset.find (“green”); if (itr != myset.end()) cout<<*itr<<endl;

ex place elements of vector into set

vector<string>vec={“purple”,”pink”}; myset.insert(vec.begin(),vec.end());

Container Adapters

are special predefined containers that are adapted to specific uses.

Not full container classes but

classes that provide specific iterface, relying on object of one of the container classes (deque, list, etc) to handle the elements.

The underlying container is encapsulated so elements are accessed by the members of the container adapter.

Queues and Stacks Data Structures can be implemented as a stack, queue or priority_queue

Page 101: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

101

1. stack

LIFO (Last In, First Out),

inserted (pushed) and removed (popped) from the end of the container.

default the standard container deque is used, maintains items to provide LIFO

Operator != Operator, <, <=, ==, >, >=

2. queue

container where elements operate in a FIFO (First In, First Out) context,

elements are inserted (pushed) to the back of the container and removed (popped) from the front.

Queues default to using deque, but can also use list.. Maintains items to provide FIFO.

Member functions

empty(), front (), push() … inserts at end, pop() … removes front, queue(), size()

3. Priority queue

Use vactor to maintain items in sorted order

Page 102: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

102

Iterators Accessing Container Elements

An Iterator is an object that can traverse (iterate over) a container class without the user having to know how the container is implemented. With many classes (particularly lists and the associative classes), iterators are the primary way elements of these classes are accessed.

Same functionality as pointers

1. Random Access Iterator nth_element

2. Bidirectional iterator

3. Forward Iterator

can only increment, ie only move forward

Max_element

upper_bound

search_n

find_first_of

adjacent_find

equal

4. Reverse Iterator rbegin()

rend()

.base

size = actual number of elements

pop = back, delete last

back = iterator points past last element

find = (first, last, value not position to find)

5. Input Iterator

can be read: x=*p;, can only move forward

6. Output Iterator

can be written: *p=x; output value, can only move forward

7. All these in const versions (except output iterators)

An iterator is best visualized as a pointer to a given element in the container, with a set of overloaded operators to provide a set of well-defined functions:

Operator* — Dereferencing the iterator returns the element that the iterator is currently pointing at.

Operator++ — Moves the iterator to the next element in the container. Most iterators also provide Operator– to move to the previous element.

Operator== and Operator!= — Basic comparison operators to determine if two iterators point to the same element. To compare the values that two iterators are

Page 103: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

103

pointing at, deference the iterators first, and then use a comparison operator.

Operator= — Assign the iterator to a new position (typically the start or end of the container’s elements). To assign the value of the element the iterator is point at, deference the iterator first, then use the assign operator.

Each container includes four basic member functions for use with Operator=:

begin() returns an iterator representing the beginning of the elements in the container.

end() returns an iterator representing the element just past the end of the elements.

cbegin() returns a const (read-only) iterator representing the beginning of the elements in the container.

cend() returns a const (read-only) iterator representing the element just past the end of the elements.

rbegin -

rend -

Implementing iterators for the array template<class T> class Array { public: typedef T* iterator; typedef unsigned size_type; Array(); Array(size_type); iterator begin() { return p_;} iterator end() { return p_+sz_;} private: T* p_; size_type sz_; }; Now allows the desired syntax: for (Array<T>::iterator p = a.begin(); p !=a.end(); ++p ) cout << *p;

Instead of for (T* p = a.p_; p !=a.p_+a.sz_; ++p ) cout << *p;

Page 104: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

104

Implementing iterators for the linked list template <class T> struct node_iterator {

Node<T>* p; node_iterator(Node<T>* q) : p(q) {} node_iterator<T>& operator++(){ p=p->next; } T* operator ->() { return &(p->value); } T& operator*() { return p->value; } bool operator!=(const node_iterator<T>& x) { return p!=x.p; }

// more operators missing … }; template<class T> class list {

Node<T>* first; public: typedef node_iterator<T> iterator; iterator begin(){ return iterator(first); } iterator end() { return iterator(0); }

}; Now also allows the desired syntax:

for (List<T>::iterator p = l.begin(); p !=l.end(); ++p) cout << *p;

Max_element

Return largest element in range

Returns an iterator pointing to the element with the largest value in the range [first,last).

template <class ForwardIterator> ForwardIterator max_element (ForwardIterator first, ForwardIterator last);

Page 105: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

105

// min_element/max_element example #include <iostream> // std::cout #include <algorithm> // std::min_element, std::max_element bool myfn(int i, int j) { return i<j; } struct myclass { bool operator() (int i,int j) { return i<j; } } myobj; int main () { int myints[] = {3,7,2,5,6,4,9}; // using default comparison: smallest element

*std::min_element(myints,myints+7) largest element

*std::max_element(myints,myints+7) // using function myfn as comp:

*std::min_element(myints,myints+7,myfn) *std::max_element(myints,myints+7,myfn) // using object myobj as comp: smallest element

*std::min_element(myints,myints+7,myobj) largest element

*std::max_element(myints,myints+7,myobj) return 0; } Output:

The smallest element is 2

The largest element is 9

The smallest element is 2

The largest element is 9

The smallest element is 2

The largest element is 9

upper_bound

function template <algorithm> std::upper_bound template <class ForwardIterator, class T> ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val); template <class ForwardIterator, class T, class Compare> ForwardIterator upper_bound ( ForwardIterator first, ForwardIterator last, const T& val, Value of the upper bound to search for in the range

Page 106: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

106

Compare comp); <map>

no ex

<set>

iterator upper_bound (const value_type& val) const;

val is value to compare

/ set::lower_bound/upper_bound #include <iostream> #include <set> int main () { std::set<int> myset; std::set<int>::iterator itlow,itup; for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90 itlow=myset.lower_bound (30); // return any below 30 itup=myset.upper_bound (60); // return any above 60 myset.erase(itlow,itup); // 10 20 70 80 90

std::cout << “myset contains:”; for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)

std::cout << ‘ ‘ << *it; std::cout << ‘\n’; return 0; }

Notice that lower_bound(30) returns an iterator to 30,

whereas upper_bound(60) returns an iterator to 70.

myset contains: 10 20 70 80 90

nth_element

void nth_element (RandomAccessIterator first,

RandomAccessIterator nth,

RandomAccessIterator last,

Compare comp);

std::nth_element (myvector.begin(), myvector.begin()+5, myvector.end());

Sort element in range

Rearranges the elements in the range [first,last), in such a way that the element at the nth position is the element that would be in that position in a sorted sequence.

Page 107: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

107

The other elements are left without any specific order, except that none of the elements preceding nth are greater than it, and none of the elements following it are less.

The elements are compared using operator< for the first version, and comp for the second.

search_n

Searches the range [first,last) for a sequence of count elements,

each comparing equal to val OR

for which pred returns true).

The function returns an iterator to the first of such elements, or last if no such sequence is found.

int myints[]={10,20,30,30,20,10,10,20};

std::vector<int> myvector (myints,myints+8);

// using default comparison:

it = std::search_n (myvector.begin(), myvector.end(), 2, 30);

Two 30s found at position 2

find_first_of

Find character in string

Searches the string for the first character that matches any of the characters specified in its arguments.

Size find_first_of (const string& str, size_t pos = 0) const;

ex

std::string str (“Please, replace the vowels in this sentence by asterisks.”); while (found!=std::string::npos) {

str[found]=‘*’; found=str.find_first_of(“aeiou”,found+1); }

output

Pl s , r pl c th v w ls n th s s nt nc by st r sks.

adjacent_find

Searches the range [first,last) for the first occurrence of two consecutive

Page 108: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

108

elements that match, and returns an iterator to the first of these two elements, or last if no such pair is found.

int myints[] = {5,20,5,30,30,20,10,10,20}; std::vector<int> myvector (myints,myints+8); std::vector<int>::iterator it; it = std::adjacent_find (myvector.begin(), myvector.end());

the first pair of repeated elements are: 30

equal

Test whether all the elements in two ranges are equal

Compares the elements in the range [first1,last1) with those in the range beginning at first2, and returns true if all of the elements in both ranges match.

if ( std::equal (myvector.begin(), myvector.end(), myints) )

Page 109: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

109

Reverse Iterators

//vector begins at one not zero vector <int> v; vector<int>::iterator i;

for (int i=0; i<10; i++) { //{0,1,2,3,4,5,6,7,8,9}

cout << “ ” << i ; v.push_back(i);

} cout << endl; i = find (v.begin(),v.end(),2) ; //will not print i, must dereference

cout << “find 2 iterator *i dereferenced =” << *i << endl;

base() = -1, converts a reverse iterator into the corresponding forward iterator

// base converts reverse_iterator to forward_iterator

// find rbegin,rend 2 = 7th position or #2

// base -1 = 6th position or #3

i = v.erase(find(v.rbegin(), v.rend(),2).base());

// erase uses forward iterator, rbegin and rend are reverse iterators

// so must convert reverse to forward iterator

// that’s why .base is used

// after erase {0,1,2,4,5,6,7,8,9}

Page 110: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

110

So, .base makes it easier to convert reverse to forward indicators.

rbegin().base() == end() and rend().base() == begin()

You can call the base() member function on a reverse iterator in order to get a real iterator back,

Thread safety

All container functions can be called concurrently by different threads on different containers. More generally, the C++ standard library functions do not read objects accessible by other threads unless those objects are directly or indirectly accessible via the function arguments, including the this pointer.

All const member functions can be called concurrently by different threads on the

same container. In addition, the member functions begin(), end(), rbegin(),

rend(), front(), back(), data(), find(), lower_bound(),

upper_bound(), equal_range(), at(), and, except in associative

containers, operator[], behave as const for the purposes of thread safety (that

is, they can also be called concurrently by different threads on the same container). More generally, the C++ standard library functions do not modify objects unless those objects are accessible, directly or indirectly, via the function’s non-const arguments, including the this pointer.

Different elements in the same container can be modified concurrently by different threads, except for the elements of std::vector<bool> (for example, a vector of std::future objects can be receiving values from multiple threads).

Iterator operations (e.g. incrementing an iterator) read, but do not modify the underlying container, and may be executed concurrently with operations on other iterators on the same container, with the const member functions, or reads from the elements. Container operations that invalidate any iterators modify the container and cannot be executed concurrently with any operations on existing iterators even if those iterators are not invalidated.

Elements of the same container can be modified concurrently with those member functions that are not specified to access these elements. More generally, the C++ standard library functions do not read objects indirectly accessible through their arguments (including other elements of a container) except when required by its specification.

In any case, container operations (as well as algorithms, or any other C++ standard library functions) may be parallelized internally as long as this does not change the user-visible results (e.g. std::transform may be parallelized, but not std::for_each which is specified to visit each element of a sequence in order)

Page 111: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

111

Algorithms in STL

mostly loops

use loop, then should use algorithm

algorithms for working with the elements of the container classes.

Nonmodifying for_each find, find_if, find_first_of adjacent_find count, count_if mismatch equal search find_end search_n

Permutations next_permutation prev_permutation

Modifying transform copy, copy_backward swap, iter_swap, swap_ranges replace, replace_if, replace_copy, replace_copy_if fill, fill_n generate, generate_n remove, remove_if, remove_copy, remove_copy_if unique, unique_copy reverse, reverse_copy rotate, rotate_copy

random_shuffle

Sorted Sequences sort,stable_sort partial_sort, partial_sort_copy nth_element lower_bound, upper_bound equal_range binary_search merge, inplace_merge partition, stable_partition

Minimum and Maximum min max min_element max_element

lexicographical_compare

Set Algorithms includes set_union set_intersection set_difference set_symmetric_difference

Page 112: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

112

Sort Algorithms

Comparison-based Sorting Algorithms

1. Quicksort

avg 2-3x faster merge or heap

little addl mem

The steps are: 1. Pick an element, called a pivot, from the array.

2. Reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.

3. Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array of elements with greater values.

Pseudocode

quicksort(A, lo, hi): if lo < hi: p := partition(A, lo, hi) quicksort(A, lo, p - 1) quicksort(A, p + 1, hi)

Quicksort is a space-optimized version of the binary tree sort. Instead of inserting items sequentially into an explicit tree, quicksort organizes them concurrently into a tree that is implied by the recursive calls.

Page 113: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

113

use in-place or external memory.

2. Heap Sort

heapsort is assumed to be on average somewhat slower than standard in-place quicksort.

Steps are 1. Heap - Maps binary tree structure into an array. Array index = node.

2. Sorted Array - Sort array be repeatedly removing largest element from heap (root) and insert into array.

3. Mergesort

divide-and-conquer paradigm

can work on linked lists, large lists on HD’s

recursive sort algorithm

Top-down implementation use indices

disadvantage - lg memory req

Conceptually, a merge sort works as follows: 3. Divide the unsorted list into n sublists, each containing 1 element (a list of 1

element is considered sorted).

4. Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.

4. Bubble Sort

Although bubble sort is one of the simplest sorting algorithms to understand and implement,

its O(n2) complexity means that its efficiency decreases dramatically on lists of more than a

small number of elements. Even among simple O(n2) sorting algorithms, algorithms like

insertion sort are usually considerably more efficient.

Pseudocode implementation

The algorithm can be expressed as (0-based array):

procedure bubbleSort( A : list of sortable items ) n = length(A) repeat swapped = false for i = 1 to n-1 inclusive do /* if this pair is out of order */ if A[i-1] > A[i] then /* swap them and remember something changed */ swap( A[i-1], A[i] ) swapped = true end if end for until not swapped

Page 114: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

114

end procedure

5. Insertion Sort 2) Disadvantage: Inefficient for large lists.

6. Shell Sort

comparison sort, meaning that it can sort items of any type for which a “less-than”

Page 115: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

115

Templates

Parameterized types, better known as templates, allow the programmer to create one function that can handle many different types. Instead of having to take into account every data type, you have one arbitrary parameter name that the compiler then replaces with the different data types that you wish the function to use, manipulate, etc.

instantiated at compile-time with the source code.

type safe.

user-defined specialization.

allow non-type parameters.

“lazy structural constraints”.

support mix-ins.

Function templates In the same section as algorithm, string, random, etc

There are class, function, member and variable (C++14) templates

Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type.

The format for declaring function templates with type parameters is:

template <class identifier> function_declaration; template <typename identifier> function_declaration;

The only difference between both prototypes is the use of either the keyword class or the keyword typename. Its use is indistinct, since both expressions have exactly the same meaning and behave exactly the same way.

For example, to create a template function that returns the greater one of two objects we could use:

template <class myType> myType GetMax (myType a, myType b) { return (a>b?a:b); }

To use this function template we use the following format for the function call:

function_name <type> (parameters);

Here is the entire example:

// function template #include <iostream>

Page 116: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

116

using namespace std; template <class T> T GetMax (T a, T b) { T result; result = (a>b)? a : b; return (result); } int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax<int>(i,j); n=GetMax<long>(l,m); cout << k << endl; cout << n << endl; return 0; }

Since both i and j are of type int, and the compiler can automatically find out that the template parameter can only be int. This implicit method produces exactly the same result:

// function template II #include <iostream> using namespace std; template <class T> T GetMax (T a, T b) { return (a>b?a:b); } int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax(i,j); n=GetMax(l,m); cout << k << endl; cout << n << endl; return 0; }

6 10

Edit & Run

Notice how in this case, we called our function template GetMax() without explicitly specifying the type between angle-brackets <>. The compiler automatically determines what type is needed on each call.

We can also define function templates that accept more than one type parameter, simply by specifying more template parameters between the angle brackets. For example:

template <class T, class U> T GetMin (T a, U b) { return (a<b?a:b); }

In this case, our function template GetMin() accepts two parameters of different types and returns an object of the same type as the first parameter (T) that is passed. For example, after that declaration we could call GetMin() with:

Page 117: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

117

int i,j; long l; i = GetMin<int,long> (j,l);

or simply:

i = GetMin (j,l);

even though j and l have different types, since the compiler can determine the appropriate instantiation anyway.

Templates, which are sometimes called parameterized types, are mechanisms for generating functions and classes based on type parameters. By using templates, you can design a single class or function that operates on data of many types, instead of having to create a separate class for each type.

Function Template w/ Multiple Parameters, order of parameters determine output

template<class T, class U> int x = 89; double y = 56.78; cout << smaller (x,y)<<endl; } (x,y) pass in int first, smaller() using first parameter to determine return type. return type is int. (x,y) pass in double first, then T = double, smaller() uses first parameter to determine return type, return type will be double, so compiler promotes y to double for comparison and return.

Page 118: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

118

Template Function Specialization

In some cases it is possible to override the template-generated code by providing special definitions for specific types. This is called template specialization. The following example demonstrates a situation where overriding the template generated code would be necessary:

#include <iostream> #include <cstring> using namespace std ; //max returns the maximum of the two elements template <class T> T max(T a, T b) { return a > b ? a : b ; } // Specialization of max for char* template <> char* max(char* a, char* b) { return strcmp(a, b) > 0 ? a : b ; } int main() {

cout << “max(10, 15) =” << max(10, 15) << endl ; cout << “max(‘k’, ‘s’) =” << max(‘k’, ‘s’) << endl ; cout << “max(10.1, 15.2) =” << max(10.1, 15.2) << endl ; cout << “max(\“Aladdin\”, \“Jasmine\”) =” << max(“Aladdin”, “Jasmine”) << endl ; return 0 ; } Program Output max(10, 15) = 15

max(‘k’, ‘s’) = s max(10.1, 15.2) = 15.2

max(“Aladdin”, “Jasmine”) = Jasmine

Page 119: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

119

template <typename T> class foo {}; class/struct

template <> class foo<int>{}; specialization template class foo<int>; explicit instantiation

Implicit Instatiation Class template Explicit Instation Class template

Implicit Instatiation function template Explicit Instation function template

template <class T>

class Z

{

public:

Z() {} ;

~Z() {} ;

void f(){} ;

} ;

int main()

{

//Implicit Instatiation Template

Z<int> zi; // generates class

Z<int>

Implicit Instatiation Class Members

zi.f();//generates function

Z<int>::f()

0

return 0 ;

}

template <class T>

class Z

{

public:

Z() {} ;

~Z() {} ;

void f(){} ;

} ;

int main()

{

//Explicit instantiation Template

template class Z<int>; //class

Z<int>

template <class T>

T Z(T a, T b)

{ return a > b ? a : b ;}

int main()

{

Implicit Instatiation Function

Template

int I ;

implicit instantiation of Z(int,

int

I = Z(10, 15) ;)

char c ;

implicit instantiation

ofmax(char,char)

c = Z('k', 's') ;

template <class T>

void Z(T r_t)

{}

int main()

{

Explicit instantiation

FunctionTemplate

explicit instantiation of Z(int)

template void Z<int>(int) ;

Page 120: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

120

Class Templates

template <typename T> class foo {}; class/struct

template <> class foo<int>{}; specialization

template class foo<int>; explicit instantiation

Normal

template <class T> class stack { private: T ddata[max]; // array of T types like ints, chars, etc. public: stack(): numElements(0) {} / constructor stack(const stack <T> & source); bool push(const T elm); bool pop(T & elm); bool isfull()const(return numElements MAX);

Template Specification If specific type passed into template then, act differently

template <class T> // Default function class spunky {

public: spunky (T x) { cout << x << “is not a character” << endl; }

};

template<> //Specialization function

class spunky<char> // what type of data should this class specialize in? public: spunky(char x) {} }; int main (){ spunky <int> // <int> datatype helps C++ know what type of data sending in

Page 121: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

121

Class Templates

template<class T> Class Earray { private: T * array; int size; public: EArray(int l); / Constructor ~Earray(); / destructor void set_element(int I, const T & newval); void erase_element(int i); void add_element (int I, const T & newval); void add_end_element(const T & newval); }; template<class T> Earray<T>::~EArray() // destructor { delete [] array; array = NULL;

Class Template

// This would go into a header file such as “Array.h” template<typename T> class Array { public: Array(int len=10):len_(len), data_(new T[len]) { } ~Array(){ delete[] data_; } int len() const { return len_;} const T& operator[](int i) const { return data_[check(i)]; } T&operator[](int i) { return data_[check(i)]; } Array(const Array<T>&); Array(Array<T>&&); Array<T>& operator= (const Array<T>&); Array<T>& operator= (Array<T>&&); private: int len_; T* data_; int check(int i) const { assert(i >= 0 && i < len_); return i; } };

Class

// This would go into a header file such as “Array.h”

class Array {

public: Array(int len=10):len_(len), data_(new int[len]) { }

~Array() { delete[] data_; }

int len() const { return len_; } const int& operator[](int i) const {

return data_[check(i)]; } int&operator[](int i){

return data_[check(i)]; }

Array(const Array&); Array& operator= (const Array&);

private: int len_;

int* data_; int check(int i) const {

if (i < 0 || i >= len_) throw BoundsViol(“Array”, i, len_); return i;

} };

Page 122: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

122

}; template <class T> void EArray<T> :: set_element (int I, const T newval) if (I < length && !>= 0) { array[i]=newval; } }

Unlike template functions, template classes (instantiations of class templates) need to be explicit about the parameters over which they are instantiating:

int main() { Array<int> ai; Array<float> af;

ex of function template

where the template parameter T does not appear in the function’s parameter list. In this case the compiler cannot deduce the template parameter types when the function is called

template<typename T> void f() { // ... }

To call this function with T being an int or a std::string, you could say:

#include <string> void sample() { f<int>();

// type T will be int in this call f<std::string>();

// type T will be std::string in this call }

ex of function template

whose template parameters appear in the function’s list of formal parameters (that is, the compiler can deduce the template type from the actual arguments):

template<typename T> void g(T x) { // ... }

Force arguments to be promoted before compiler deduces the template type

Code g(42) calls gets g<int>(42) g<long>(42) g<long>(42)) Promote explicitly,

doesn’t use template g(“xyz”) calls g<char*>(char*)

g<std::string>(“xyz”) promote explicitly

Page 123: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

123

Array<char*> ac; Array<std::string> as; Array<Array<int>> aai; // ... }

Template to swap two integers vs writing a swap for floats, longs, Strings, Sets, and FileSystems

void swap(int& x, int& y) { int tmp = x; x = y; y = tmp; }

hence a function template: A “template function” is the instantiation of a “function” template

template<typename T> void swap(T& x, T& y) { T tmp = x; x = y; y = tmp; }

Which version of function template should get called?

When you call a function template, the compiler tries to deduce the template type

Most of the time it can do that successfully, but every once in a while you may want to help the compiler deduce the right type — either because it cannot deduce the type at all, or perhaps because it would deduce the wrong type.

Must specify the types is when the function takes two parameters of the same type, but you give it two different types.

Defining member functions of a template class

Defining member functions of a template class is somewhat like defining a function template, except for the fact, that you use the scope resolution operator to indicate that this is the template classes’ member function. The one important and non-obvious detail is the requirement of using the template operator containing the parametrized type name after the class name.

The following example describes the required syntax by defining functions from the example class above.

template <class T> Foo<T>::Foo()

Since m and n have different types, the compiler can’t deduce what type to use for T

template<typename T> void g(T x, T y); int m = 0; long n = 1; g(m, n);

so you have to tell it what to use:

template<typename T> void g(T x, T y); int m = 0; long n = 1;

g<int>(m, n);

Page 124: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

124

{ member_variable = 0; } template <class T> void Foo<T>::some_function() { cout << “member_variable =” << member_variable << endl; } template <class T> T Foo<T>::some_other_function() { return parametrized_variable; }

As you may have noticed, if you want to declare a function that will return an object of the parametrized type, you just have to use the name of that parameter as the function’s return type.

Angle Bracket Placement

For example:

TempClass< float, (a > b ? a : b) > test1; NOT TempClass< float, a > b ? a : b > test1;

template type constructed from a template parameter:

T<int>, MyTemplate<T>

A class template is a class with a parameter, such as:

// what_are_templates3.cpp template <class T> class A { T m_t; public: A(T t): m_t(t) {} void f(T t); }; int main() { A<int> a(10); } Previously shown ex function template template <class T> T GetMax (T a, T b) { T result;

The individual classes or functions created are referred to as instantiated.

For example, a class template: template <class T> struct A { . . . };

can be used to instantiate classes for A<int>, A<char>, A<int*>, A<MyClass*>, and

Page 125: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

125

so on.

You can use class templates to create a family of classes that operate on a type. Class templates are parameterized types. They imply that a separate class could be created for each conceivable value of the parameters (known as template arguments) passed in.

Template arguments can be types or constant values of a specified type. For example:

// class_templates.cpp template <class T, int i> class TempClass { public: TempClass( void ); ~TempClass( void ); int MemberSet( T a, int b ); private: T Tarray[i]; int arraysize; }; int main() { }

Members of class templates

defined outside of the class declaration,

they must be declared differently than those of nontemplated classes.

The declaration must be preceded by syntax specifying the template class that the function is a member of.

template < template-argument-list > definition

Page 126: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

126

Nested Class Templates

member templates - Templates defined within classes or class templates,

nested class templates - Member templates that are classes, defined inside or outside the enclosing class.

Member Function Templates - Member templates that are functions

explicitly instantiate the class by giving the arguments for the class templates. Unlike function templates,

To create an instance of TempClass: TempClass< float, 6 > test1; // OK TempClass< char, items++ > test2; // Error, second parameter // must be constant.

The compiler generates code for a template class or function when the class or function is instantiated.

member function is instantiated when it is called

virtual member function is instantiated when its class is constructed.

An explicit specialization of a template is a customized version of the template for a particular type.

Class Instantiation or functions Instantation

1. Explicit instantiation is a way of calling out in code what versions of the template are to be generated.

2. Implicit instantiation allows templates to be instantiated as needed at the point where they are first used.

The template-parameter-list is a comma-separated list of template parameters, which may be types (in the form class identifier, typename identifier, or template < template-parameter-list > class identifier) or non-type parameters to be used in the template body. The syntax for a template parameter is one of the following:

parameter-declaration class identifier [ = typename ] typename identifier [ = typename ] template < template-parameter-list > class [identifier][= name]

Class Tempalte Instantation

must include the template arguments within angle brackets (<>).

These template arguments can be any type if the template argument list contains the class or typename keyword, or a value of the appropriate type if the argument is a non-type argument.

template< class T, int i > class MyStack...

In this case, the template can receive a type (class T) and a constant parameter (int i). The template will use type T and the constant integer i upon instantiation. Within the body of the MyStack declaration, you must refer to the T identifier.

A template declaration itself does not generate code; it specifies a family of classes or functions, one or more of which will be generated when referenced by other code.

Template declarations have global, namespace, or class scope. They cannot be declared within a function.

Page 127: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

127

1.

// class templates #include <iostream> using namespace std; template <class T> // <class T> the T = template parameter class mypair { T a, b; public: mypair (T first, T second) {a=first; b=second;} T getmax (); }; template <class T> // <class T> the T = template parameter T mypair<T>::getmax () // T = type returned by the function

// <T> specifies that this function’s template // parameter is also the class template parameter { T retval; retval = a>b? a : b; return retval; } int main () { mypair <int> myobject (100, 75); cout << myobject.getmax(); return 0; }

OUTPUT 100

Page 128: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

128

Templates and Friends Friendship can be established between

a class template and a global function,

a member function of another class (possibly a template class),

or even an entire class (possible template class).

The table below lists the results of declaring different kinds of friends of a class.

Class Template

friend declaration in class template X

Results of giving friendship

template class <T> class X

friend void f1() ; makes f1() a friend of all instantiations of template X.

ex, f1() is a friend of X<int>, X<A>, and X<Y>.

template class <T> class X

friend void f2(X<T>&) ;

For a particular type T

ex. float, makes f2(X<float>&) a friend of class X<float> only.

f2(x<float>&) cannot be a friend of class X<A>.

template class <T> class X

friend A::f4() ;

// A is a user defined class with a member function f4() ;

makes A::f4() a friend of all instantiations of template X.

ex, A::f4() is a friend of X<int>, X<A>, and X<Y>.

template class <T> class X

friend C<T>::f5(X<T>&) ;

// C is a class template with a member function f5

For a particular type T

ex, float, makes C<float>::f5(X<float>&) a friend of class X<float> only.

C<float>::f5(x<float>&) cannot be a friend of class X<A>.

template class <T> class X

friend class Y ; makes every member function of class Y a friend of every template class produced from the class template X.

template class <T> class X

friend class Z<T> ;

when a template class is instantiated with a particular type T, such as a float, all members of class Z<float> become friends of template class X<float>.

Page 129: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

129

Template specialization An instantiated object of a templated class is called a specialization; the term specialization is useful to remember because it reminds us that the original class is a generic class, whereas a specific instantiation of a class is specialized for a single datatype (although it is possible to template multiple types)

If we want to define a different implementation for a template when a specific type is passed as template parameter, we can declare a specialization of that template.

For example, let’s suppose that we have a very simple class called mycontainer that can store one element of any type and that it has just one member function called increase, which increases its value. But we find that when it stores an element of type char it would be more convenient to have a completely different implementation with a function member uppercase, so we decide to declare a class template specialization for that type:

2.

// template specialization #include <iostream> using namespace std; // class template: template <class T> class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () {return ++element;} }; // class template specialization: template <> class mycontainer <char> { char element; public: mycontainer (char arg) {element=arg;} char uppercase () {

if ((element>=‘a’)&&(element<=‘z’)) element+=‘A’-’a’; return element; } }; int main () { mycontainer<int> myint (7);

mycontainer<char> mychar (‘j’); cout << myint.increase() << endl; cout << mychar.uppercase() << endl; return 0; }

8

J Edit & Run

This is the syntax used in the class template specialization:

template <> class mycontainer <char> { ... };

Page 130: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

130

First of all, notice that we precede the class template name with an empty template<> parameter list. This is to explicitly declare it as a template specialization.

But more important than this prefix, is the <char> specialization parameter after the class template name. This specialization parameter itself identifies the type for which we are going to declare a template class specialization (char). Notice the differences between the generic class template and the specialization:

3. template <class T> class mycontainer { ... }; template <> class mycontainer <char> { ... };

4.

Non-type parameters for templates Besides the template arguments that are preceded by the class or typename keywords , which represent types, templates can also have regular typed parameters, similar to those found in functions. As an example, have a look at this class template that is used to contain sequences of elements:

// sequence template #include <iostream> using namespace std; template <class T, int N> class mysequence { T memblock [N]; public: void setmember (int x, T value); T getmember (int x); }; template <class T, int N> void mysequence<T,N>::setmember (int x, T value) { memblock[x]=value; } template <class T, int N> T mysequence<T,N>::getmember (int x) { return memblock[x]; } int main () { mysequence <int,5> myints; mysequence <double,5> myfloats; myints.setmember (0,100); myfloats.setmember (3,3.1416);

cout << myints.getmember(0) << ‘\n’; cout << myfloats.getmember(3) << ‘\n’; return 0; }

Output

100

3.1416

It is also possible to set default values or types for class template parameters. For example, if the previous class template definition had been:

Page 131: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

131

template <class T=char, int N=10> class mysequence {..};

Template friends Both function template and class template declarations may appear with the friend specifier in any non-local class or class template

class A { template<typename T> friend class B; // every B<T> is a friend of A template<typename T> friend void f(T) {} // every f<T> is a friend of A

(although only function templates may be defined within the class or

class template that is granting friendship).

In this case, every specialization of the template becomes a friend, whether it is implicitly instantiated, partially specialized, or explicitly specialized.

Friend declarations cannot refer to partial specializations, but can refer to full specializations:

template<class T> class A {}; // primary template<class T> class A<T*> {}; // partial template<> class A<int> {}; // full class X { template<class T> friend class A<T*>; // error! friend class A<int>; // OK };

When a friend declaration refers to a full specialization of a function template, the keyword inline and default arguments cannot be used.

template<class T> void f(int); template<> void f<int>(int); class X { friend void f<int>(int x = 1); // error: default args not allowed };

If a member of a class template A is declared to be a friend of a non-template class B, the corresponding member of every specialization of A becomes a friend of B. If A is explicitly specialized, as long as there is a member of the same name, same kind (type, function, class template, function template), same parameters/signature, it will be a friend of B.

template<typename T> // primary template struct A { }; template<> struct A<int> // full specialization {

Page 132: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

132

struct C {}; }; class B // non-template class { template<class T> friend struct A<T>::C; // A<int>::C is a friend, as well as all A<T>::C template<class T> friend void A<T>::f(); // A<int>::f() is not a friend, because the // signatures do not match, but A<char>::f() is template<class T> friend void A<T>::D::g(); // A<int>::D::g() is not a friend: it is not a member // of A, and A<int>::D is not a specialization of A<T>::D };

Member Initialization:

Foo(int num): bar(num) Simply said, it initializes your member bar to a value num.

What is the difference between Initializing and Assignment inside a constructor?

3. Member Initializing Foo(int num): bar(num) {}; // equal to Foo(int num) : bar() {bar = num;}

When you initialize fields via Member initializer list the constructors will be called once and the object will be constructed and initialized in one operation.

4. Member Assignment: Foo(int num) {

bar = num; // equal to Foo(int num): bar(num){} }

If you use assignment then the fields will be first initialized with default constructors and then reassigned (via assignment operator) with actual values.

As you see there is an additional overhead of creation & assignment in the latter, which might be considerable for user defined classes.

Cost of Member Initialization = Object Construction Cost of Member Assignment = Object Construction + Assignment

Page 133: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

133

When do you HAVE TO use Member Initializer list?

Your class has a reference member

Your class has a non static const member or

Your class member doesn’t have a default constructor or

For initialization of base class members or

When constructor’s parameter name is same as data member(this is not really a MUST)

A code example:

class MyClass { public: //Reference member, has to be Initialized in Member Initializer List int &i; int b; //Non static const member, must be Initialized in Member Initializer List const int k;

//Constructor’s parameter name b is same as class data member //Other way is to use this->b to refer to data member MyClass(int a, int b, int c):i(a),b(b),k(c) { //Without Member Initializer //this->b = b; } }; class MyClass2:public MyClass { public: int p; int q; MyClass2(int x,int y,int z,int l,int m):MyClass(x,y,z),p(l),q(m) { } }; int main() { int x = 10; int y = 20; int z = 30; MyClass obj(x,y,z); int l = 40; int m = 50; MyClass2 obj2(x,y,z,l,m); return 0; }

MyClass2 doesn’t have a default constructor so it has to be initialized through member initializer list.

Base class MyClass does not have a default constructor, So to initialize its

Page 134: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

134

member one will need to use Member Initializer List.

Class Member variables are always initialized in the order in which they are declared in the class.

Page 135: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

135

Accessing Object members variables and methods

3 distinct operators C++ uses to access the members of a class or class object

The . (dot) operator and the -> (arrow) operator are used to reference individual members of classes, structures, and unions.

The dot operator is applied to the actual object. The arrow operator is used with a pointer to an object.

pointer

-> pointer to object

accessing object member variables and methods via pointer to object

Foo *foo = new Foo(); foo->member_var = 10; foo->member_func();

instance

. object instance

a.b is only used if b is a member of the object (or reference to an object) a. So for a.b, a will always be an actual object (or a reference to an object) of a class.

. for accessing object member variables and methods via object instance

Foo foo; foo.member_var = 10; foo.member_func();

class/struct or namespace

::

a::b is only used if b is a member of the class (or namespace) a. That is, in this case a will always be the name of a class (or namespace).

for accessing static variables and methods of a class/struct or namespace.

It can also be used to access variables and functions from another scope (actually class, struct, namespace are scopes in that case)

int some_val = Foo::static_var; Foo::static_method(); int max_int = std::numeric_limits<int>::max();

In C++ you can access fields or methods, using different operators, depending on it’s type:

Page 136: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

136

ClassName::FieldName : class public static field and methods

The :: operator is known as the scope resolution operator, and it is used to get from a namespace or class to one of its members.

The . and -> operators are for accessing an object instance’s members, and only comes into play after creating an object instance.

ClassInstance.FieldName : accessing a public field (or method) through class reference

. if you have an actual object (or a reference to the object, declared with & in the

declared type)

ClassPointer->FieldName : accessing a public field (or method) dereferencing a class pointer

-> if you have a pointer to an object (declared with * in the declared type).

Example 1:

class Aclass{ public: static int static_field; int instance_field; static void static_method(); void method(); };

then you access this way:

Aclass instance; instance.instance_field; //access instance_field through a reference to Aclass instance.method(); Aclass *pointer = new AClass(); pointer->instance_field; //access instance_field through a ptr to Aclass pointer->method(); Aclass::static_field; Aclass::static_method()

The this object is always a pointer to the current instance, hence why the -> operator is the only one that works.

Example 2:

Page 137: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

137

// In a header file namespace Namespace { class Class { private: int x; public: Class() : x(4) {} void incrementX(); }; } // In an implementation file namespace Namespace { void Class::incrementX() {//Using scope resolution to get to the

// class member when we aren’t using an // instance ++(this->x); //* this is a pointer, so using ->. //Equivalent to ++((*this).x) } } // In a separate file lies your main method int main() { Namespace::Class myInstance; // instantiates an instance. Note the //scope resolution Namespace::Class *myPointer = new Namespace::Class; myInstance.incrementX(); // Calling a function on an object // instance. myPointer->incrementX(); // Calling a function on an object // pointer. (*myPointer).incrementX(); // Calling a function on an object // pointer by dereferencing first return 0; }

Page 138: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

138

Const-ness

Constant Method const is “qualifier”

const enforces const-ness at compile time

self documenting

2 rules to remember

const on right of *, pointer is const const on left of *, data is const const on left and right of *, both are const

char* the_string : OK change the char to which the_string points, and I can modify the char at

which it points.

const char* the_string : OK change the char to which the_string points, but I cannot modify the

char at which it points.

char* const the_string : I cannot change the char to which the_string points, but I can modify the

char at which it points.

const char* const the_string : I cannot change the char to which the_string points, nor can I

modify the char at which it points.

change the char to which the_string points

modify the char at which it points

char*

the_string Y Y

const char*

the_string Y --NO--

char* const

the_string --NO-- Y

const char* const

the_string --NO-- --NO--

class A { private: int n; public: A() { n=1; } void output() const; // const method // const means output will //not modify anything // inside its class. // that is int n // output will be printing // squared will be returning a squared integer // Let compiler and other programmers know by

Page 139: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

139

// inserting const void A::output() const { cout << n << endl; } int A::squared() const { return (n*n); }

cast away const-ness const int I = 9; const_cast<int&>(i) = 6; now I can be changed

Namespace Namespaces allow us to group a set of global classes, objects and/or functions under a name. Split the global scope into sub-scopes known as namespaces. The form to use namespaces is:

namespace identifier { namespace-body } //Where identifier is any valid identifier and namespace-body is the set of classes, objects and functions that are included within the namespace. For example:

namespace general { int a, b; }

//In this case, a and b are normal variables integrated within the general namespace. In order to access to these variables from outside the namespace we have to use the scope operator ::. For example, to access the previous variables we would have to put:

general::a general::b

The functionality of namespaces is specially useful in case that there is a possibility that a global object or function can have the same name than another one, causing a redefinition error. Ex

#include <iostream> using namespace std; // first name space namespace first_space{ void func(){

cout << “Inside first_space” << endl; } } // second name space namespace second_space{ void func(){

cout << “Inside second_space” << endl; } } int main () { // Calls function from first name space. first_space::func(); // Calls function from second name space. second_space::func(); return 0; }

If we compile and run above code, this would produce the following result:

Inside first_space

Page 140: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

140

Inside second_space

Page 141: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

141

Static Class member, Static Function Member

Static member variables

only one exists in a program shared across all objects of that class. like a "class global".

A static variable declared in a header file outside of the class would be file-scoped in every .c file which includes the header. That means separate copy of a variable with same name is accessible in each of the .c files where you include the header file.

A static class variable on the other hand is class-scoped and the same static variable is available to every compilation unit that includes the header containing the class with static variable.

static variables keep their values and are not destroyed even after they go out of scope.

Access static member variable static int s_nValue;

through object of the class type cFirst.s_nValue which is misleading, implying that s_nValue belongs to cFirst. BUT s_nValue does not belong to any object. In fact, s_nValue exists even if there are no objects of the class that have been instantiated.

it is better to think of static members as belonging to the class itself, not the objects of the class. Because s_nValue exists independently of any class objects, it can be accessed directly using the class name and the scope operator:

Something::s_nValue;

Static member functions

Static member variable that’s private

class Something { private: static int s_nValue; }; int Something::s_nValue = 1; // have to initialize outside of main int main() {

Problem: can’t access s_nValue inside main since it’s private

Solution : make member functions static. class Something { private: static int s_nValue; public: //static member function static int GetValue() { return s_nValue; } };

Page 142: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

142

int Something::s_nValue = 1; // initializer int main() { std::cout << Something::GetValue() << std::endl; = s_nValue }

Like static member variables, static member functions are not attached to any particular object.

Quirk # 1: static member functions are not attached to an object, they have no this pointer!

Quirk # 2: static member functions can only access static member variables. They can not access non-static member variables. This is because non-static member variables must belong to a class object, and static member functions have no class object to work with!

Page 143: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

143

1) Static Member Functions

2) Non-Static Member Functions

Static Member Functions Non-Static Member Functions

The important thing in the syntax here are the parentheses around obj.*f, which basically bind the pointer to the object whose member function we are calling.

Static Function Members: (Static Member Function)

1. Persistence:

pointers to static member functions. class myclass { public: // define function Static void myfunc(int x) { }; // declare a type for a pointer typedef void ( *StaticFunc ) ( int ); // assign address of member function StaticFunc f = myclass::myfunc; f ( 123 ); // call the function via function pointer }

Not assoc with any - object instance, they look like ordinary function pointers. No ‘this’ ptr.

cannot be - virtual, const or volatile

access to only - static members

class myclass { public: Static void myfunc(int x) { }; typedef void ( *StaticFunc ) ( int ); StaticFunc f = myclass::myfunc;

pointers to non-static member functions.

class myclass { public: // declare a type for a pointer typedef void ( myclass::*myfunc ) ( int );

// instantiate class with object myclass obj;

// assign address of member function Func f = &myclass::myfunc;

// and call it ( obj.*f ) ( 123 );

access to ‘this’ ptr

class myclass { public: typedef void ( myclass::*myfunc ) ( int ); myclass obj; Func f = &myclass::myfunc; ( obj.*f ) ( 123 );

pointer to non-member function (ordinary function)

Page 144: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

144

it remains in memory until the end of the program.

Given a fixed block of memory, not on stack or heap.

2. File scope:

it can be seen only with in a file where it’s defined.

3. Visibility:

if it is defined within a function/block, it’s scope is limited to the function/block. It cannot be accessed outside of the function/block/modules.

Non-Static Member Functions can access

all data members (functions and vars) of the class: static and non-static.

Static Member Function can access

static member data,

other static member functions outside the class

Static Member Function instance can access

either static or non-static

4. Class: Class scope

static members exist as members of the class rather than as an instance in each object of the class. So, “this” object pointer is not available in a static member function. Such functions may access only static data members. There is only a single instance of each static data member for the entire class

5. A static data member :

class variable

6. A non-static data member :

instance variable

7. can be called even if no objects of the class exist

8. accessed using only the class name and the scope resolution operator ::.

9. You could use a static member function to determine whether some objects of the class have been created or not.

10. extern

External linkage means that a symbol in one translation unit can be accesses from the other translation units. Unless we take special steps, the functions and global variables in our .cpp will have external linkage.

One way of avoid this linkage issue is using static keyword:

static const int MY_CONSTANT = 199;

static std::string MY_NAME = “BoGo”; static void My_Function() {}

An extern declaration does not define the variable unless it is also initialized in the same statement.

Page 145: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

145

extern int x; // declaration extern int x = 10; // definition

if we want to make a constant have external linkage, we can use the extern keyword to override the default internal linkage:

extern const int a = 20;

Here, we should use the extern keyword to declare the constant in all files that use the constant. That’s the difference between regular external variables and constant.

For regular external variables, we don’t use the keyword extern when we define a variable, but we use extern in other files using that variable.

11. member is initialized outside the class definition,

we must use fully qualified name when we initialize it:

class_name::static_member_name = value;

The exception to the initialization of a static data member inside the class declaration is if the static data member is a const of integral or enumeration type.

class Car { enum Color {silver = 0, maroon, red }; int year; int mileage = 34289; // error: not-static data members // only static const integral data members // can be initialized within a class static int vin = 12345678;// error: non-constant data member // only static const integral data members // can be initialized within a class

Static Objects

Static object is an object that persists from the time it’s constructed until the end of the program.

But global objects,

objects at namespace scope,

objects declared static inside classes/functions, and

objects declared at file scope

are included in static objects

How to access static variables in class #include <iostream> using namespace std; class myclass { static int i; // private by default // declaration of static variable does not define it // Must define it outside the class. // This is just a rule to remember.

// Also, since it’s private can only access by // get and set method which is assigned in the clss. // As displayed beloe. public: void setInt(int n) {

Page 146: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

146

i = n; } int getInt() { return i; } };

int myclass::i; // Definition of myclass::i. i is still private to myclass. int main() { myclass object1, object2; object1.setInt(10);

cout << “object1.i:” << object1.getInt() << ‘\n’; // displays 10 cout << “object2.i:” << object2.getInt() << ‘\n’; // also displays 10 return 0; }

static member variables don’t refer to an instanciated object, but to the whole class.

To use them you have to include the class scope, I mean ClassName::a (assuming your class is named ClassName).

When you declare a variable in a function, the static keyword specifies that the variable retains its state between calls to that function.

Page 147: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

147

Interview Question - What’s static?

This is one of the frequently asked questions during the interview. Most of the candidates get the first one, and some with the second, third, and may be 4th ones as well. But rarely they address the 5th one:

1. A variable declared static within the body of a function maintains its value between invocations of the function.

2. A variable declared static within a module (but outside the body of a function) is accessible by all functions within that module. However, it is not accessible by functions from other modules.

3. static members exist as members of the class rather than as an instance in each object of the class. There is only a single instance of each static data member for the entire class.

4. Non-static member functions can access all data members of the class: static and non-static. Static member functions can only operate on the static data members.

5. C functions declared static within a module may only be called by other functions within that module (file scope).

By declaring a function member as static, you make it independent of any particular object of the class. A static member function can be called even if no objects of the class exist and the static member functions are accessed using only the class name and the scope resolution operator ::

ex

include <iostream> class Test { public:

static void DoCrash(){ std::cout<< “TEST IT!”<< std::endl; } }; int main() { Test k; // calling a static method like a member method, not necessary k.DoCrash(); // Normal without instance Test::DoCrash();

std::system( “pause ”); return 0; }

Page 148: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

148

You could use a static member function to determine whether some objects of the class have been created or not.

#include <iostream> using namespace std; class A { public: // This declares it. static int x; static int getX(){return x;} };

// Now you need an create the object so // This must be done in once source file (at file scope level) int A::x = 100; int main() { A::x = 200; // Note no int here. You can modify it cout<<A::getX(); // Should work return 0; }

private static constant for a class

define your static member outside the class definition and provide the initailizer there.

}

// In a header file (if it is in a header file in your case) class A { private: static const string RECTANGLE; // initialize here and it fails. }; // can only Declare static members // In one of the implementation files // have to be defined outside of the class.

const string A::RECTANGLE = “rectangle”;

Static members of a C++ class We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.

A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can’t put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.

Let us try the following example to understand the concept of static data members:

Page 149: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

149

#include <iostream> using namespace std; class Box { public: static int objectCount; // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) {

cout <<“Constructor called.” << endl; length = l; breadth = b; height = h; // Increase every time object is created objectCount++; } double Volume() { return length * breadth * height; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Initialize static member of class Box int Box::objectCount = 0; int main(void) { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 // Print total number of objects.

cout << “Total objects: ” << Box::objectCount << endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Constructor called. Constructor called. Total objects: 2

.

Exam question

The following example shows an illegal access to non-static member from a static member function.

class X { public: int x; static void f(int); }; void X::f(int z) {x=z;}

Page 150: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

150

In function f(), x=z is an error because f(), a static member function, is trying to access non-static member x.

So, the fix should be like this:

class X { public: static int x; static void f(int); }; void X::f(int z) {x=z;}

Static Function Setup

1. Declaration - Declare variable or function static

2. - ex int test::a = 0;

Q - How a static member function can call a non static member function without passing class instance

Answer class GlobalClass // Define a new type { private: int m_value; static GlobalClass *s_instance; // Declaration

//static means there’s ust one of it, and all instances share it GlobalClass(int v = 0) { m_value = v; } public: int get_value() { return m_value; } void set_value(int v) { m_value = v; } static GlobalClass *instance()

// don’t need instance of GlobalClass to invoke instance() { if (!s_instance) s_instance = new GlobalClass; // new = create instance, // pointer to this new instance is being saved as a static member of the same class that defines the type of the instance you just created! return s_instance; } };

Page 151: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

151

GlobalClass *GlobalClass::s_instance = 0; // Define void foo(void) { //returns s_instance which is a static member variable. GlobalClass::instance()->set_value(1); // reads static class variable which is allowed // variable holds a pointer, when dereferenced (via ->)results in one objedt // we created earlier and that object, since it is an instance of Global Class // is not allowed to access an instance variable. // //

// static methods can’t access non-static mehtods // but an instance (static or non-static) can access both

cout << “foo: global_ptr is ” << GlobalClass::instance()-

C++ has a rather nice feature in std::function. You could use templated pointers if you so

desired, but std::function generally results in things being neater.

Code example from the reference page on this site: // function example #include <iostream> // std::cout #include <functional> // std::function, std::negate // a function: int half(int x) {return x/2;} // a function object class: struct third_t { int operator()(int x) {return x/3;} }; // a class with data members: struct MyValue { int value; int fifth() {return value/5;} }; int main () { std::function<int(int)> fn1 = half; // function std::function<int(int)> fn2 = &half; // function pointer std::function<int(int)> fn3 = third_t(); // function object std::function<int(int)> fn4 = [](int x){return x/4;}; // lambda expression std::function<int(int)> fn5 = std::negate<int>(); // standard function object std::cout << "fn1(60): " << fn1(60) << '\n'; std::cout << "fn2(60): " << fn2(60) << '\n'; std::cout << "fn3(60): " << fn3(60) << '\n'; std::cout << "fn4(60): " << fn4(60) << '\n'; std::cout << "fn5(60): " << fn5(60) << '\n'; // stuff with members: std::function<int(MyValue&)> value = &MyValue::value; // pointer to data member std::function<int(MyValue&)> fifth = &MyValue::fifth; // pointer to member function MyValue sixty {60};

Page 152: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

152

std::cout << "value(sixty): " << value(sixty) << '\n'; std::cout << "fifth(sixty): " << fifth(sixty) << '\n'; return 0; }

Page 153: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

153

Callback / Function Pointer

Problem:

How can you build a component such that it can call a member function of another object whose type is unknown at the time the component is designed

Solution:

A callback, offer a generic connection point which developers can use to establish communication with application objects. At some subsequent point, the component 'calls back' the application object. The communication takes the form of a function call, since this is the way objects interact in C++.

Example:

Want a BUTTON component in a GUI library to call an application-specific object when clicked.

2 types

1. pointers to ordinary C functions / static C++ member functions.

2. pointers to non-static C++ member functions. hidden argument this-pointer The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class. Always keep in mind: These two types of function pointers are incompatible with each other.

Page 154: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

154

Function pointer is a variable, must define as such.

Parse a function pointer int (*pfi)(); // pointer to a function which will return an int. // (*pfi) pointer first // (*pfi) () pointer to a function // int function returns an int // ( ) around *pfi is for precedence // *pfi() is wrong, declares a function returning a pointer to int

Use a function pointer

Declare function pointer

typedef int (*funcptr) (); //Easier when use typedefs, // synonym for type

// “pointer to function returning int”

funcptr pfi extern int f1(); // Declare some functions extern int f2();

Assign function pointer

pfi = &f1; if (x=1) pfi = &f2; else pfi = &f3;

Parse the function pointer with args Get down to data, pfi now points to a function, we can call that function

pfi = name of function pointer variable

*pfi = take the contents of that pointer

(*pfi) (arg1, arg2) = append an argument list in parentheses

(*pfi) (arg1, arg2 = call the function pfi, passing it the arguments arg1 and arg2, and take the contents of the pointer it returns.

Define a function pointer and initialize to NULL int (TMyClass::*pt2Member)(float, char, char) = NULL; int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;

Assign an address to a Function Pointer class TMyClass { public: int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<<

Page 155: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

155

endl; return a+b+c;}; int DoMore(float a, char b, char c) const { cout << "TMyClass::DoMore" << endl; return a-b+c; }; /* more of TMyClass */ }; pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator pt2Member = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore

Invoke a callback std::function can store and invoke anything callable.

Callable in C++ are functions, lambda expressions, std::bind expressions, function objects, and pointers to member functions.

Calling a Function using a Function Pointer

TMyClass* instance2 = new TMyClass; int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointer delete instance2;

Pass a function pointer as a function's calling argument / <pt2Func> is a pointer to a function which returns an int and takes a float and two char

void PassPtr(int (*pt2Func)(float, char, char)) { int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer

cout << result << endl; } // 'DoIt' is a suitable function like defined above in 2.1-4 void Pass_A_Function_Pointer() { cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl; PassPtr(&DoIt); }

How to Return a Function Pointer ? It's a little bit tricky but a function pointer can be a function's return value.

In the following example there are two solutions of how to return a pointer to a function which is taking two float arguments and returns a float.

f you want to return a pointer to a member function you have just got to change the definitions/declarations of all function pointers.

How to Return a Function Pointer Function takes a char and returns a pointer to a // function which is taking two floats and returns a float. <opCode> // specifies which function to return float (*GetPtr1(const char opCode))(float, float) { if(opCode == '+') return &Plus;

Page 156: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

156

else return &Minus; // default if invalid operator was passed } // Solution using a typedef: Define a pointer to a function which is taking // two floats and returns a float typedef float(*pt2Func)(float, float); // Function takes a char and returns a function pointer which is defined // with the typedef above. <opCode> specifies which function to return pt2Func GetPtr2(const char opCode) { if(opCode == '+') return &Plus; else return &Minus; // default if invalid operator was passed } // Execute example code void Return_A_Function_Pointer() { cout << endl << "Executing 'Return_A_Function_Pointer'" << endl; // define a function pointer and initialize it to NULL float (*pt2Function)(float, float) = NULL; pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1' cout << (*pt2Function)(2, 4) << endl; // call function using the pointer pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2' cout << (*pt2Function)(2, 4) << endl; // call function using the pointer }

How to Use Arrays of Function Pointers ? Operating with arrays of function pointers is very interesting.

This offers the possibility to select a function using an index.

The syntax appears difficult, which frequently leads to confusion.

1) Use a typedef

2) directly defines the array.

// type-definition: 'pt2Member' now can be used as type typedef int (TMyClass::*pt2Member)(float, char, char); // illustrate how to work with an array of member function pointers void Array_Of_Member_Function_Pointers() { cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;

Page 157: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

157

// define arrays and ini each element to NULL, // <funcArr1> and <funcArr2> are arrays with 10 pointers // to member functions which return an int and take // a float and two char // first way using the typedef pt2Member funcArr1[10] = {NULL}; // 2nd way of directly defining the array int (TMyClass::*funcArr2[10])(float, char, char) = {NULL}; // assign the function's address - 'DoIt' and 'DoMore' are suitable // functions of class TMyClass like defined above in 2.1-4 [1] = &TMyClass::DoIt; funcArr1[1] = funcArr2[0] = &TMyClass::DoMore; /* more assignments */ // calling a function using an index to address the member function pointer // note: an instance of TMyClass is needed to call the member functions TMyClass instance; cout << (instance.*funcArr1[1])(12, 'a', 'b') << endl; cout << (instance.*funcArr1[0])(12, 'a', 'b') << endl; cout << (instance.*funcArr2[1])(34, 'a', 'b') << endl; cout << (instance.*funcArr2[0])(89, 'a', 'b') << endl; http://www.newty.de/fpt/fpt.html#chapter2

Page 158: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

158

C++11 New Functionality

auto Variables - Compiler knows what you mean

Range-Based for Loop

Automatic iterator over arrays and STL collections

provide begin() and end() and an input iterator over the elements int numbers [] = …; for (int n: numbers) std:: cout <<n; std::map<std::string, std::list<int>>M; for (const auto& pair : M) for (auto n : pair.second) std::cout << pair.first << ‘ ‘ << pair.second

C++11 augmented the for statement to support the "foreach" paradigm of iterating over collections. In the new form, it is possible to iterate over C-like arrays, initializer lists and anything for which the non-member begin() and end() functions are overloaded.

This for each for is useful when you just want to get and do something with the elements of a collection/array and don't care about indexes, iterators or number of elements.

std::map<std::string, std::vector<int>> map; std::vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); map["one"] = v; for(const auto& kvp : map) { std::cout << kvp.first << std::endl; for(auto v : kvp.second) { std::cout << v << std::endl; } } int arr[] = {1,2,3,4,5}; for(int& e : arr) { e = e*e; }

Initializer Lists

Lambda Functions

Inline methods in other methods std::list<int> ns = ...; auto print_num = [](int n) { std::cout << n; }; std::for_each(ns.begin(), ns.end(), print_num); int even = std::count_if(ns.begin(), ns.end(), [](int n) { return n&1==0; });

Page 159: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

159

// Print squares std::transform(ns.begin(), ns.end(), std::ostream_iterator<int>(std::cout, 'n'), [](int n) { return n*n; }); Lambda Functions

Capturing external local variables

Compiled to a function object with fields int fib1 = 1, fib2 = 1; auto next_step = [&]() { //capture by reference int temp = fib2; fib2 = fib2 + fib1; fib1 = temp; }; for (int i = 0; i < 20; ++i) next_step(); std::thread t([=]() { // capture by value std::cout << fib1 << std::endl; }); t.join();

Design your APIs with lambdas in mind Usually through template parameters

Invest in re-learning STL algorithms

template <typename Callback> void enum_windows(const string& title, Callback callback) { . . . callback(current_window); } template <typename RAIter, typename Comparer> void superfast_sort(RAIter from, RAIter to, Comparer cmp);

Lambdas and Function Pointers Stateless lambdas are convertible to function pointers!

&& Enable Move Construction my_array(const my_array& other) { //copy ctor dataptr_ = new T[size_ = other.size_]; memcpy_s(dataptr_, size_*sizeof(T), other.dataptr_, size_*sizeof(T)); } my_array& operator=(const my_array& other) { /*same deal*/ } my_array& operator=(my_array&& other) { //move assignment dataptr_ = other.dataptr_; size_ = other.size_; other.dataptr_ = nullptr; other.size_ = 0; } my_array(my_array&& other) { //move ctor *this = std::move(other); //NOTE: other is an lvalue }

Delegating Constructors You can now call a constructor from another constructor

Page 160: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

160

Alias Templates Typedefs can now be templates

The using keyword can replace typedef completely

Non-Static Data Member Initializers Data members can be initialized inline

The compiler adds the appropriate code prior to each constructor

class counter { int count = 0; SRWLOCK lock { SRWLOCK_INIT }; public: // ... };

New Smart Pointers

unique_ptr:

should be used when ownership of a memory resource does not have to be shared (it doesn't have a copy constructor), but it can be transferred to another unique_ptr (move constructor exists).

shared_ptr:

should be used when ownership of a memory resource should be shared (hence the name).

weak_ptr:

holds a reference to an object managed by a shared_ptr, but does not contribute to the reference count; it is used to break dependency cycles (think of a tree where the parent holds an owning reference (shared_ptr) to its children, but the

children also must hold a reference to the parent; if this second reference was also an owning one, a cycle would be created and no object would ever be released).

auto_ptr is obsolete and should no longer be used.

Function Return Type Deduction Functions can be declared as returning auto, and the compiler deduces the return type (if consistent)

Page 161: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

161

C++11 Lambda Functions

C++11 introduces many handy new features to the language. One of them is lambda

functions. A lambda function is an anonymous, temporary, usually small function. By

combining the new std::function with a lambda function that looks very similar to the above

function pointer approach, we can have a pretty decent callback mechanism.

The Callee in this case is a normal member function. Note that I've thrown in a member m_i

to show that the "this" pointer is indeed correct.

class Callee { public: Callee(int i) : m_i(i) { } // The callback function that Caller will call. int callbackFunction(int i) { printf(" Callee::callbackFunction() inside callback\n"); return m_i * i; } private: // To prove "this" is indeed valid within callbackFunction(). int m_i; };

In main(), we see the connection being made with a lambda. Like the static function in the C

function pointer approach, the lambda captures the "this" pointer so that it can get into the

class. The lambda syntax is a tad obtuse. This is probably the only real drawback to this

approach.

Caller caller; Callee callee(5); // Connect the callback. Like with the C-style function pointer and // static function, we use a lambda to get back into the object. caller.connectCallback( [&callee](int i) { return callee.callbackFunction(i); }); // Test the callback caller.test();

If you aren't familiar with lambda functions in C++, here's a quick breakdown. "[&callee]"

says to "capture" callee by reference. This basically means to make the variable "callee"

available within the lambda function. We do this by reference to avoid a copy which would

be disastrous. "(int i)" says that our lambda function takes a single int parameter. This

matches callbackFunction(). Within the braces is the code for the lambda function. In this

case we simply delegate the call to callbackFunction(). Note that we do not specify the return

type of our lambda function because C++11 is clever and will figure it out automatically.

The caller uses the straightforward std::function to store the callback and the actual call is

very simple.

Page 162: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

162

typedef std::function<int(int)> CallbackFunction; class Caller { public: // Clients can connect their callback with this. void connectCallback(CallbackFunction cb) { m_cb = cb; } // Test the callback to make sure it works. void test() { printf("Caller::test() calling callback...\n"); int i = m_cb(10); printf("Result (50): %d\n", i); } private: // The callback provided by the client via connectCallback(). CallbackFunction m_cb; };

This is so close to perfection. The only drawback is that the lambda function syntax is

slightly bizarre. Other than that, the rest of this is pretty much perfect.

Page 163: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

163

Auto Variable (Automatic Variable)

new in C+11

type deduction with regards to whether it will resolve to a value or a reference?

int x = 4;

can now be replaced with

auto x = 4;

The rule is simple : it is how you declare it.

int i = 5;

auto a1 = i; // value

auto & a2 = i; // reference

This, of course, is not the intended use of auto at all! It really shines when working with templates and iterators:

vector<int> vec; auto itr = vec.iterator(); // instead of vector<int>::iterator itr

There are other times where auto comes in handy, too. For example, let’s say that you had some code of the form:

template <typename BuiltType, typename Builder> void makeAndProcessObject (const Builder& builder) { BuiltType val = builder.makeObject(); // do stuff with val }

In this code, you can see that there are two necessary template parameters--one for the type of the “builder” object, and a second for the type of the object being built. Even worse, the type of the built object cannot be deduced by the template parameter. Every call must look like this:

MyObjBuilder builder; makeAndProcessObject<MyObj>( builder );

But auto immediately reduces this ugliness to nothing because you no longer need to be able to write the specific type at the point where you build the object. You can let C++ do it for you:

template <typename Builder> voidmakeAndProcessObject (const Builder& builder) { auto val = builder.makeObject(); // do stuff with val }

Now you only need a single template parameter, and that parameter is easily

Page 164: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

164

inferred when calling the function:

MyObjBuilder builder; makeAndProcessObject( builder );

Function objects A function object is any object for which the function call operator is defined. C++ provides many built-in function objects as well as support for creation and manipulation of new function objects.

Page 165: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

165

C++14 New Functionality

Major C++14 features can be grouped in three areas: lambda functions, constexpr, and type deduction.

Lambda functions C++14 generic lambdas make it possible to write:

auto lambda = [](auto x, auto y) {return x + y;};

On the other hand, C++11 requires that lambda parameters be declared with concrete types, e.g:

auto lambda = [](int x, int y) {return x + y;};

Furthermore, the new standard std::move function can be used to capture a variable in a lambda expression by moving the object instead of copying or referencing it:

std::unique_ptr ptr(new int(10)); auto lambda = [value = std::move(ptr)] {return *value;};

Constexpr A constexpr-declared function in C++11 is a function which can be executed at compile time to produce a value to be used where a constant expression is required, such as when instantiating a template with an integer argument. While C++11 constexpr functions could only contain a single expression, C++14 relaxes those restrictions by allowing conditional statements such as if and switch, and also allowing loops, including range-based for loops.

Type deduction C++14 allows return type deduction for all functions, thus extending C++11 that only allows it for lambda functions:

auto DeducedReturnTypeFunction();

Since C++14 is a strongly-typed language, a few restrictions shall be taken into account:

If a function's implementation has multiple return statements, they must deduce the same type.

Return type deduction can be used in forward declarations, but the function definitions must be available to the translation unit that uses them before they can be used.

Page 166: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

166

Return type deduction can be used in recursive functions, but the recursive call must be preceded by at least one return statement allowing to deduce the return type.

Another improvement to type deduction brought by C++14 is the decltype(auto) syntax, which allows to compute the type of a given expression using the same mechanism as auto. Both auto and decltype were already present in C++11, but they used different mechanisms to deduce types that could end up in producing different results.

Other changes in C++14 include the possibility of declaring variables that are templated and using binary literals specified using the prefixes 0b or 0B. InfoQ has already covered other minor changes in C++14 that could break C++11 programs.

Support for the new language features is well underway on major C++ compilers: Clang "fully implements all of the current draft"; GCC and Visual Studio also offer some support for C++14 new features.

InfoWorld | Aug 19, 2014

Generic lambdas - you can now write lambda parameters with an auto type and the

compiler will figure things out.

Lambdas parameters move - you can std::move things into the lambda (before this only

copy or reference were possible)

Constexpr - it can now have if, switch or for statements and local variables in a

constexpr

Return type deduction - auto myFunction() { }

digit separators - you can now write 1'000'000 instead of 1000000

binary literals - 0b prefix

sized deallocation - you can now have a global overload to delete for all sized

allocations (pretty cool!)

std::gets removed - apparently using fgets is the recommended safe way

dynamic memory management - reworked spec + optimizations

deprecated keyword - [[deprecated]] for marking things, calling deprecated

functions/using deprecated members gives a compiler warning

make_unique - finally!

metaprogramming support - improved transformation traits, compile time integer

sequences

stl improvements - null iterators

variable templates - template<typename T> constexpr T x = T(5); I'm not sure

how/when you would use this ..

shared_mutex is now called shared_timed_mutex

Page 167: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

167

random - std::random_shuffle is deprecated (std::rand was almost deprecated as well,

just discouraged for now). added 4 new random related functions

aggregated member init heterogeneous lookup in associative containers - things like using const char* as a key

to lookup in a map from std::string to something. this works if you have an operator<

overload, also std::less and std::greater support this

standard user-defined literals - you can write chrono::duration d = 60s; (now alos h,

min, s, ms, us, ns)

tuple addressing via type - being able to fetch a tuple by type (not just by index)

global std::cend/std::cbegin - const counterparts to std::end/std::begin, globally

std::quoted - for insertion and extraction of quoted strings

Page 168: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

168

Functors: Function Objects in C++

function pointers, which provide a way to pass around instructions on how to perform an operation.

limited because functions must be fully specified at compile time.

Functors are objects that can be treated as though they are a function or function pointer--you could write code that looks like this:

MyClass myFunctor; cout << myFunctor(137) << endl; // “Call” myFunctor with parameter 137

Although myFunctor is an object, in the second line of code we treat it as though it were a function by invoking it with the parameter 137.

To create a functor, we create an object that overloads the function call operator, operator (). The name of this function is a bit misleading – it is a function called operator

(), not a function called operator that takes no parameters. Despite the fact that the name looks like “operator parentheses,” we’re not redefining what it means to parenthesize the object. Instead, we’re defining a function that gets called if we invoke the object like a function. Thus in the above code,

cout << myFunctor(137) << endl;

is equivalent to

cout << myFunctor.operator()(137) << endl;

Unlike other operators we’ve seen so far, when overloading the function call operator, you’re free to return an object of any type (or even void) and can accept any number of parameters. Remember that the point of operator overloading is to allow objects to act like built-in types, and since a regular function can have arbitrarily many parameters and any return type, functors are allowed the same freedom.

For example, here’s a sample functor that overloads the function call operator to print out a string:

class MyFunctor { public:

void operator() (const string& str) const { cout << str << endl; }

};

Note that in the function definition there are two sets of parentheses. The first group is for the function name – operator () – and the second for the parameters to operator (). If we separated the implementation of operator () from the class definition, it would look like this: class MyFunctor { public: void operator() (const string& str) const; };

Page 169: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

169

void MyFunctor::operator() (const string& str) const { cout << str << endl; }

Now that we’ve written MyFunctor, we can use it as follows:

MyFunctor functor; functor(“Functor power!”);

The key difference between a function and a functor is that a

A functor’s function call operator is a member function whereas a raw C++ function is a free function. This means that a functor can access the following information when being called:

• Its local variables.

• Its parameters. • Global variables.

• Class data members. key difference between a regular function and a functor.

If a functor’s operator() member function requires access to data beyond what can be communicated by its parameters, we can store that information as a data member inside the functor class. Since operator() is a member of the functor class, it can then access that data freely. example functor class: class StringAppender { public: /* Constructor takes and stores a string. */ explicit StringAppender(const string& str) : toAppend(str) {} /* operator() prints out a string, plus the stored suffix. */ void operator() (const string& str) const {

cout << str << ‘ ‘ << toAppend << endl; } private: const string toAppend; };

This functor’s constructor takes in a string and stores it for later use. Its operator ()

function accepts a string, then prints that string suffixed with the string stored by the constructor. We can then use the

StringAppender functor like this:

StringAppender myFunctor(“is awesome”); myFunctor(“C++”);

This code will print out “C++ is awesome,” since the constructor stored the string “is

Page 170: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

170

awesome” and we passed “C++” as a parameter to the function. If you’ll notice, though, in the actual function call we only passed in one piece of information – the string “C++.” This is precisely why functors are so useful. Like regular functions, functors are invoked with a fixed number of parameters. Unlike raw functions, however, functors can be constructed to store as much information is necessary to solve the task at hand.

// this is a functor

struct add_x { add_x(int x) : x(x) {} int operator()(int y) { return x + y; } private: int x; };

// Now you can use it like this:

add_x add42(42); // create an instance of the functor class int i = add42(8); // and “call” it assert(i == 50); // and it added 42 to its argument

Initialization list But what if you have a parent class that needs to take arguments to its constructor? This is where initialization lists come into play. An initialization list immediately follows the constructor’s signature, separated by a colon:

1. Calling base class constructors

2. Initialising member variables before the body of the constructor executes.

3. pass arguments to the parent class’s constructor

4. pass arguments to your member variables’ constructors

For case #2, the question may be asked: “Why not just initialise it in the body of the

constructor?” The importance of the initialisation lists is particularly evident for const members. For instance, take a look at this situation, where I want to initialise m_val based on the constructor parameter:

Page 171: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

171

: m_val(val) is called initialization list,

It is a way to initialize some of the fields of your object with values of your choice, instead of leaving them as undefined.

To be clear - in addition to initializing const members, it’s the only way to initialize reference members, whether const or not (since an assignment to a reference is an assignment to what the reference refers to).

Constructor’s signature is

MyClass() it is a parameterless constructor, the default constructor MyClass() : m_classID(-1), m_userdata(0) is called initialization list

In C++, whenever an object of a class is created, its constructor is called. But that’s not all--its parent class constructor is called, as are the constructors for all objects that belong to the class. By default, the constructors invoked are the default (“no-argument”) constructors. Moreover, all of these constructors are called before the class’s own constructor is called.

For instance, take the following code:

#include <iostream> class Foo { public:

Foo() { std::cout << “Foo’s constructor” << std::endl; } }; class Bar : public Foo { public:

Bar() { std::cout << “Bar’s constructor” << std::endl; } }; int main()

class Demo { Demo(int& val) { m_val = val; } private: const int& m_val; };

By the C++ specification, this is illegal. We cannot change the value of a const variable in the constructor, because it is marked as const. So you can use the initialisation list:

class Demo { Demo(int& val) : m_val(val) { } private: const int& m_val; };

That is the only time that you can change a const member variable

Page 172: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

172

{ // a lovely elephant ;) Bar bar; }

The object bar is constructed in two stages: first, the Foo constructor is invoked and then the Bar constructor is invoked.

Why do this? There are a few reasons. First, each class should need to initialize things that belong to it, not things that belong to other classes. So a child class should hand off the work of constructing the portion of it that belongs to the parent class. Second, the child class may depend on these fields when initializing its own fields; therefore, the constructor needs to be called before the child class’s constructor runs. In addition, all of the objects that belong to the class should be initialized so that the constructor can use them if it needs to.

But what if you have a parent class that needs to take arguments to its constructor? This is where initialization lists come into play. An initialization list immediately follows the constructor’s signature, separated by a colon:

class Foo : public parent_class {

Foo() : parent_class( “arg” ) // sample initialization list {

// you must include a body, even if it’s merely empty } };

Note that to call a particular parent class constructor, you just need to use the name of the class (it’s as though you’re making a function call to the constructor).

For instance, in our above example, if Foo’s constructor took an integer as an argument, we could do this:

#include <iostream> class Foo { public: Foo( int x ) {

std::cout << “Foo’s constructor” << “called with” << x << std::endl; } }; class Bar : public Foo { public: Bar() : Foo( 10 ) // construct the Foo part of Bar {

std::cout << “Bar’s constructor” << std::endl; } }; int main() { Bar stool; }

Page 173: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

173

Using Initialization Lists to Initialize Fields In addition to letting you pick which constructor of the parent class gets called, the initialization list also lets you specify which constructor gets called for the objects that are fields of the class. For instance, if you have a string inside your class:

class Qux { public:

Qux() : _foo( “initialize foo to this!” ) { } // This is nearly equivalent to

// Qux() { _foo = “initialize foo to this!”; } // but without the extra call to construct an empty string private: std::string _foo; };

Here, the constructor is invoked by giving the name of the object to be constructed rather than the name of the class (as in the case of using initialization lists to call the parent class’s constructor).

If you have multiple fields of a class, then the names of the objects being initialized should appear in the order they are declared in the class (and after any parent class constructor call):

class Baz { public:

Baz() : _foo( “initialize foo first” ), _bar( “then bar” ) { } private: std::string _foo; std::string _bar; };

Initialization Lists and Scope Issues If you have a field of your class that is the same name as the argument to your constructor, then the initialization list “does the right thing.” For instance,

class Baz { public: Baz( std::string foo ) : foo( foo ) { } private: std::string foo; }; is roughly equivalent to class Baz { public: Baz( std::string foo ) { this->foo = foo; } private: std::string foo; };

That is, the compiler knows which foo belongs to the object, and which foo belongs to the function.

Page 174: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

174

When Else do you Need Initialization Lists? No Default Constructor

If you have a field that has no default constructor (or a parent class with no default constructor), you must specify which constructor you wish to use.

Initialization Lists and Exceptions Since constructors can throw exceptions, it’s possible that you might want to be able to handle exceptions that are thrown by constructors invoked as part of the initialization list.

First, you should know that even if you catch the exception, it will get rethrown because it cannot be guaranteed that your object is in a valid state because one of its fields (or parts of its parent class) couldn’t be initialized. That said, one reason you’d want to catch an exception here is that there’s some kind of translation of error messages that needs to be done.

The syntax for catching an exception in an initialization list is somewhat awkward: the ‘try’ goes right before the colon, and the catch goes after the body of the function:

class Foo {

Foo() try : _str( “text of string” ) { } catch ( ... ) { std::cerr << “Couldn’t create _str”;

// now, the exception is rethrown as if we’d written // “throw;” here } };

Initialization Lists: Summary Before the body of the constructor is run, all of the constructors for its parent class and then for its fields are invoked. By default, the no-argument constructors are invoked. Initialization lists allow you to choose which constructor is called and what arguments that constructor receives.

If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.

Sorting Mail Now we can think about how we’d want to write a mail sorting functor. We’d need operator() to take two messages, and we can have its constructor store the field we wish to sort by.

class Message { public:

Page 175: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

175

std::string getHeader (const std::string& header_name) const; // other methods... }; class MessageSorter { public: // take the field to sort by in the constructor MessageSorter (const std::string& field) : _field( field ) {} bool operator() (const Message& lhs, const Message& rhs) { // get the field to sort by and make the comparison return lhs.getHeader( _field ) < rhs.getHeader( _field ); } private: std::string _field; };

Now if we had a vector of Messages, we could use the STL sort function to sort them:

std::vector<Message> messages; // read in messages MessageSorter comparator; sort( messages.begin(), messages.end(), comparator );

Functors Compared with Function Pointers If you have a function that takes a function pointer, you cannot pass in a functor as though it were a function pointer, even if the functor has the same arguments and return value as the function pointer.

Likewise, if you have a function that expects a functor, you cannot pass in a function pointer.

Functors, Function Pointers, and Templates If you wish to allow either a function pointer or a functor to be passed into the same function, you need to use templates. The templated function will deduce the proper type for the functor or function pointer, and both functors and function pointers are used in the exact same way--they both look like function calls--so the code in the function will compile fine.

For instance, let’s say you had this simple little find_matching_numbers function that takes a vector and returns a vector of all numbers for which a given function returns true.

std::vector<int> find_matching_numbers (std::vector<int> vec, bool (*pred)(int)) { std::vector<int> ret_vec;

Page 176: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

176

std::vector<int>::iterator itr = vec.begin(), end = vec.end(); while ( itr != end ) { if ( pred( *itr ) ) { ret_vec.push_back( *itr ); } ++itr; } }

We could quickly convert this function to allow either functors or function pointers by templating on the type of the second argument:

template <typename FuncType> std::vector<int> find_matching_numbers( std::vector<int> vec, FuncType pred ) { std::vector<int> ret_vec; std::vector<int>::iterator itr = vec.begin(), end = vec.end(); while ( itr != end ) { if ( pred( *itr ) ) { ret_vec.push_back( *itr ); } ++itr; } }

Notice that this also lets you avoid having to use the rather convoluted function pointer syntax. Sweet!

Page 177: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

177

Functors vs. Virtual Functions Functors and virtual functions are, believe it or not, closely related. They both solve the same problem: how do we let some code choose the algorith that is applied. Imagine that you have a function called doMath, and it takes 3 arguments: two integers, and a “kind of math to do”. You could write it with functors like this:

template <FuncType> int doMath (int x, int y, FuncType func) { return func( x, y ); }

Another way that you could write this is by creating an interface class that has a computeResult method:

class MathComputer { virtual int computeResult (int x, int y) = 0; }; doMath (int x, int y, MathComputer* p_computer) { return p_computer->computeResult( x, y ); }

Admittedly, this is kind of a boring example! All it shows you is that both virtual functions and functors allow you to dynamically choose the exact algorithm that is executed.

The major difference is that using virtual functions does not give the ability to write a templated function that can also accept function pointers. Depending on your application, this may be important: if you’re writing a library, it’s probably very important; if you’re writing a small program for yourself, it’s likely less important. A virtual function, on the other hand, has somewhat simpler syntax (no complex templates!) and tends to fit the normal object-oriented programming mindset.

Page 178: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

178

C++ Web Server Configuration, CGI, Post, Get

*************************************

*************************************

The Common Gateway Interface (CGI) is a standard protocol for enabling applications (called CGI programs or CGI scripts) to interact with Web servers and with clients.

CGI library allows CGI programming to communicate with Web Server’s like Apache to run CGI programs on HTTP servers and run on HTML browers

http://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm

Go to this link later and take notes

HTTP Header

CGI Environment Variables

C++ CGI Library

GET and POST Methods

Simple FORM Example: GET Method

Passing Radio Button Data to CGI Program

Passing Text Area Data to CGI Program

Page 179: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

179

Page 180: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

180

Lambda Functions in C++11 - the Definitive Guide So are lambda functions really going to start showing up all over the place in C++ code when the language has survived for decades without them? I think so--I’ve started using lambda functions in production code, and they are starting to show up all over the place--in some cases shortening code, in some cases improving unit tests, and in some cases replacing what could previously have only been accomplished with macros. So yeah, I think lambdas rock way more than any other Greek letter.

Lambda functions are available in GCC 4.5 and later, as well as MSVC 10 and version 11 of the

Intel compiler.

One of the most exciting features of C++11 is ability to create lambda functions (sometimes referred to as closures). What does this mean? A lambda function is a function that you can write inline in your source code (usually to pass in to another function, similar to the idea of a functor or function pointer). With lambda, creating quick functions has become much easier, and this means that not only can you start using lambda when you’d previously have needed to write a separate named function, but you can start writing more code that relies on the ability to create quick-and-easy functions. In this article, I’ll first explain why lambda is great--with some examples--and then I’ll walk through all of the details of what you can do with lambda.Why Lambdas Rock

Imagine that you had an address book class, and you want to be able to provide a search function. You might provide a simple search function, taking a string and returning all addresses that match the string. Sometimes that’s what users of the class will want. But what if they want to search only in the domain name or, more likely, only in the username and ignore results in the domain name? Or maybe they want to search for all email addresses that also show up in another list. There are a lot of potentially interesting things to search for. Instead of building all of these options into the class, wouldn’t it be nice to provide a generic “find” method that takes a procedure for deciding if an email address is interesting? Let’s call the method findMatchingAddresses, and have it take a “function” or “function-like” object.

#include <string> #include <vector> class AddressBook { public: // using a template allows us to ignore the differences between functors, function pointers and lambda template<typename Func> std::vector<std::string> findMatchingAddresses (Func func) { std::vector<std::string> results; for ( auto itr = _addresses.begin(), end = _addresses.end(); itr != end; ++itr ) { // call the function passed into findMatchingAddresses and see if it matches if ( func( *itr ) ) { results.push_back( *itr ); } }

Page 181: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

181

return results; } private: std::vector<std::string> _addresses; };

Anyone can pass a function into the findMatchingAddresses that contains logic for finding a particular function. If the function returns true, when given a particular address, the address will be returned. This kind of approach was OK in earlier version of C++, but it suffered from one fatal flaw: it wasn’t quite convenient enough to create functions. You had to go define it somewhere else, just to be able to pass it in for one simple use. That’s where lambdas come in.

Basic Lambda Syntax Before we write some code to solve this problem, let’s see the really basic syntax for lambda.

#include <iostream> using namespace std; int main() {

auto func = [] () { cout << “Hello world”; }; func(); // now call the function }

Okay, did you spot the lambda, starting with []? That identifier, called the capture specification, tells the compiler we’re creating a lambda function. You’ll see this (or a variant) at the start of every lambda function.

Next up, like any other function, we need an argument list: (). Where is the return value? Turns out that we don’t need to give one. In C++11, if the compiler can deduce the return value of the lambda function, it will do it rather than force you to include it. In this case, the compiler knows the function returns nothing. Next we have the body, printing out “Hello World”. This line of code doesn’t actually cause anything to print out though--we’re just creating the function here. It’s almost like defining a normal function--it just happens to be inline with the rest of the code.

It’s only on the next line that we call the lambda function: func() -- it looks just like calling any other function. By the way, notice how easy this is to do with auto! You don’t need to sweat the ugly syntax of a function pointer.

Applying Lambda in our Example

Let’s look at how we can apply this to our address book example, first creating a simple function that finds email addresses that contain “.org”.

AddressBook global_address_book; vector<string> findAddressesFromOrgs () { return global_address_book.findMatchingAddresses(

// we’re declaring a lambda here; the [] signals the start

Page 182: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

182

[] (const string& addr) { return addr.find( “.org” ) != string::npos; } ); }

Once again we start off with the capture specifier, [], but this time we have an argument--the address, and we check if it contains “.org”. Once again, nothing inside the body of this lambda function is executed here yet; it’s only inside findMatchingAddresses, when the variable func is used, that the code inside the lambda function executes.

In other words, each loop through findMatchingAddresses, it calls the lambda function and gives it the address as an argument, and the function checks if it contains “.org”.

Variable Capture with Lambdas

Although these kinds of simple uses of lambd are nice, variable capture is the real secret sauce that makes a lambda function great. Let’s imagine that you want to create a small function that finds addresses that contain a specific name. Wouldn’t it be nice if you could write code something like this?

// read in the name from a user, which we want to search string name; cin>> name; return global_address_book.findMatchingAddresses(

// notice that the lambda function uses the the variable ‘name’ [&] (const string& addr) { return addr.find( name ) != string::npos; } );

It turns out that this example is completely legal--and it shows the real value of lambda. We’re able to take a variable declared outside of the lambda (name), and use it inside of the lambda. When findMatchingAddresses calls our lambda function, all the code inside of it executes--and when addr.find is called, it has access to the name that the user passed in. The only thing we needed to do to make it work is tell the compiler we wanted to have variable capture. I did that by putting [&] for the capture specification, rather than []. The empty [] tells the compiler not to capture any variables, whereas the [&] specification tells the compiler to perform variable capture.

Isn’t that marvelous? We can create a simple function to pass into the find method, capturing the variable name, and write it all in only a few lines of code. To get a similar behavior without C++11, we’d either need to create an entire functor class or we’d need a specialized method on AddressBook. In C++11, we can have a single simple interface to AddressBook that can support any kind of filtering really easily.

Just for fun, let’s say that we want to find only email addresses that are longer than a certain number of characters. Again, we can do this easily:

Page 183: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

183

int min_len = 0; cin >> min_len; return global_address_book.find( [&] (const string& addr) { return addr.length() >= min_len; } );

By the way, to steal a line from Herb Sutter, you should get used to seeing “} );” This is the standard end-of-function-taking-lambda syntax, and the more you start seeing and using lambda in your own code, the more you’ll see little piece of syntax.

Lambda and the STL

One of the biggest beneficiaries of lambda functions are, no doubt, power users of the standard template library algorithms package. Previously, using algorithms like for_each was an exercise in contortions. Now, though, you can use for_each and other STL algorithms almost as if you were writing a normal loop. Compare:

vector<int> v; v.push_back( 1 ); v.push_back( 2 ); //... for ( auto itr = v.begin(), end = v.end(); itr != end; itr++ ) { cout << *itr; } with vector<int> v; v.push_back( 1 ); v.push_back( 2 ); //... for_each( v.begin(), v.end(), [] (int val) { cout << val; } );

That’s pretty good looking code if you ask me--it reads, and is structured, like a normal loop, but you’re suddenly able to take advantage of the goodness that for_each provides over a regular for loop--for example, guarantees that you have the right end condition. Now, you might wonder, won’t this kill performance? Well, here’s the kicker: it turns out that for_each has about the same performance, and is sometimes even faster than a regular for loop. (The reason: it can take advantage of loop unrolling.)

If you’re interested in more on C++11 lambda and the benefits to the STL, you’ll enjoy this video of Herb Sutter talking about C++11 lambdas.

I hope this STL example shows you that lambda functions are more than just a slightly more convenient way of creating functions--they allow you to create entirely new ways of writing programs, where you have code that takes other functions as data and allows you to abstract away the proccessing of a particular data structure. for_each works on a list, but wouldn’t it be great to have similar functions for working with trees, where all you had to do was right some code that would process each node, and not have to worry about the traversal algorithm? This kind of

Page 184: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

184

decomposition where one function worries about the structure of data, while delegating the data processing to another function can be quite powerful. With lambda, C++11 enables this new kind of programming. Not that you couldn’t have done it before--for_each isn’t new--it’s just that you wouldn’t have wanted to do it before.

More on the new Lambda Syntax

By the way, the parameter list, like the return value is also optional if you want a function that takes zero arguments. Perhaps the shortest possible lambda expression is:

[] {}

Which is a function that takes no arguments and does nothing. An only slightly more compelling example:

using namespace std; #include <iostream> int main() {

[] { cout << “Hello, my Greek friends”; }(); }

Personally, I’m not yet sold on omitting the argument list; I think the [] () structure tends to help lambda functions stand out a little more in the code, but time will tell what standards people come up with.

Return Values

By default, if your lambda does not have a return statement, it defaults to void. If you have a simple return expression, the compiler will deduce the type of the return value:

[] () { return 1; } // compiler knows this returns an integer

If you write a more complicated lambda function, with more than one return value, you should specify the return type. (Some compilers, like GCC, will let you get away without doing this, even if you have more than one return statement, but the standard doesn’t guarantee it.)

Lambdas take advantage of the optional new C++11 return value syntax of putting the return value after the function. In fact, you must do this if you want to specify the return type of a lambda. Here’s a more explicit version of the really simple example from above:

[] () -> int { return 1; } // now we’re telling the compiler what we want

Page 185: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

185

Throw Specifications Although the C++ standards committee decided to deprecate throw specifications (except for a few cases I’ll cover in a later article), they didn’t remove them from the language, and there are tools that do static code analysis to check exception specifications, such as PC Lint. If you are using one of these tools to do compile time exception checking, you really want to be able to say which exceptions your lambda function throws. The main reason I can see for doing this is when you’re passing a lambda function into another function as an argument, and that function expects the lambda function to throw only a specific set of exceptions. By providing an exception spec for your lambda function, you could allow a tool like PC Lint to check that for you. If you want to do that, it turns out you can. Here’s a lambda that specifies that it takes no arguments and does not throw an exception:

[] () throw () { /* code that you don’t expect to throw an exception*/ }

How are Lambda Closures Implemented? So how does the magic of variable capture really work? It turns out that the way lambdas are implemented is by creating a small class; this class overloads the operator(), so that it acts just like a function. A lambda function is an instance of this class; when the class is constructed, any variables in the surrounding enviroment are passed into the constructor of the lambda function class and saved as member variables. This is, in fact, quite a bit like the idea of a functor that is already possible. The benefit of C++11 is that doing this becomes almost trivially easy--so you can use it all the time, rather than only in very rare circumstances where writing a whole new class makes sense.

C++, being very performance sensitive, actually gives you a ton of flexibility about what variables are captured, and how--all controlled via the capture specification, []. You’ve already seen two cases--with nothing in it, no variables are captured, and with &, variables are captured by reference. If you make a lambda with an empty capture group, [], rather than creating the class, C++ will create a regular function. Here’s the full list of options:

[] Capture nothing (or, a scorched earth strategy?) [&] Capture any referenced variable by reference [=] Capture any referenced variable by making a copy [=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference

[bar] Capture bar by making a copy; don’t copy anything else [this] Capture the this pointer of the enclosing class

Notice the last capture option--you don’t need to include it if you’re already specifying a default capture (= or &), but the fact that you can capture the this pointer of a function is super-important because it means that you don’t need to make a distinction between local variables and fields of a class when writing lambda functions. You can get access to both. The cool thing is that you don’t need to explicitly use the this pointer; it’s really like you are writing a function inline.

class Foo { public: Foo () : _x( 3 ) {}

Page 186: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

186

void func () { // a very silly, but illustrative way of printing out the value of _x [this] () { cout << _x; } (); } private: int _x; }; int main() { Foo f; f.func(); }

Dangers and Benefits of Capture by Reference When you capture by reference, the lambda function is capable of modifying the local variable outside the lambda function--it is, after all, a reference. But this also means that if you return a lamba function from a function, you shouldn’t use capture-by-reference because the reference will not be valid after the function returns.

What type is a Lambda?

The main reason that you’d want to create a lambda function is that someone has created a function that expects to receive a lambda function. We’ve already seen that we can use templates to take a lambda function as an argument, and auto to hold onto a lambda function as a local variable. But how do you name a specific lambda? Because each lambda function is implemented by creating a separate class, as you saw earlier, even single lambda function is really a different type--even if the two functions have the same arguments and the same return value! But C++11 does include a convenient wrapper for storing any kind of function--lambda function, functor, or function pointer: std::function.

std::function

The new std::function is a great way of passing around lambda functions both as parameters and as return values. It allows you to specify the exact types for the argument list and the return value in the template. Here’s out AddressBook example, this time using std::function instead of templates. Notice that we do need to use the ‘functional’ header file.

#include <functional> #include <vector> class AddressBook { public: std::vector<string> findMatchingAddresses (std::function<bool (const string&)> func) { std::vector<string> results; for ( auto itr = _addresses.begin(), end = _addresses.end(); itr != end; ++itr ) { // call the function passed into findMatchingAddresses and see if it matches

Page 187: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

187

if ( func( *itr ) ) { results.push_back( *itr ); } } return results; } private: std::vector<string> _addresses; };

One big advantage of std::function over templates is that if you write a template, you need to put the whole function in the header file, whereas std::function does not. This can really help if you’re working on code that will change a lot and is included by many source files.

If you want to check if a variable of type std::function is currently holding a valid function, you can always treat it like a boolean:

std::function<int ()> func;

// check if we have a function (we don’t since we didn’t provide one) if ( func ) { // if we did have a function, call it func(); }

A Note About Function Pointers

Under the final C++11 spec, if you have a lambda with an empty capture specification, then it can be treated like a regular function and assigned to a function pointer. Here’s an example of using a function pointer with a capture-less lambda:

typedef int (*func)(); func f = [] () -> int { return 2; }; f();

This works because a lambda that doesn’t have a capture group doesn’t need its own class--it can be compiled to a regular old function, allowing it to be passed around just like a normal function. Unfortunately, support for this feature is not included in MSVC 10, as it was added to the standard too late.

Making Delegates with Lambdas Let’s look at one more example of a lambda function--this time to create a delegate. What’s a delgate, you ask? When you call a normal function, all you need is the function itself. When you call a method on an object, you need two things: the function and the object itself. It’s the difference between func() and obj.method(). To call a method, you need both. Just passing in the address of the method into a function isn’t enough; you need to have an object to call the method on.

Let’s look at an example, starting with some code that again expects a function as an argument, into which we’ll pass a delegate.

#include <functional> #include <string>

Page 188: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

188

class EmailProcessor { public: void receiveMessage (const std::string& message) { if ( _handler_func ) { _handler_func( message ); } // other processing } void setHandlerFunc (std::function<void (const std::string&)> handler_func) { _handler_func = handler_func; } private: std::function<void (const std::string&)> _handler_func; };

This is a pretty standard pattern of allowing a callback function to be registered with a class when something interesting happens.

But now let’s say we want another class that is responsible for keeping track of the longest message received so far (why do you want to do this? Maybe you are a bored sysadmin). Anyway, we might create a little class for this:

#include <string> class MessageSizeStore { public: MessageSizeStore () : _max_size( 0 ) {} void checkMessage (const std::string& message ) { const int size = message.length(); if ( size > _max_size ) { _max_size = size; } } int getSize () { return _max_size; } private: int _max_size; };

What if we want to have the method checkMessage called whenever a message arrives? We can’t just pass in checkMessage itself--it’s a method, so it needs an object.

EmailProcessor processor; MessageSizeStore size_store;

processor.setHandlerFunc( checkMessage ); // this won’t work

We need some way of binding the variable size_store into the function passed to setHandlerFunc. Hmm, sounds like a job for lambda!

EmailProcessor processor; MessageSizeStore size_store; processor.setHandlerFunc(

Page 189: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

189

[&] (const std::string& message) { size_store.checkMessage( message ); } );

Isn’t that cool? We are using the lambda function here as glue code, allowing us to pass a regular function into setHandlerFunc, while still making a call onto a method--creating a simple delegate in C++.

Page 190: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

190

Exceptions try-block

Associates one or more exception handlers (catch-clauses) with a compound statement.

Syntax

try compound-statement handler-sequence

where handler-sequence is a sequence of one or more handlers, which have the following syntax:

catch ( attr(optional) type-specifier-seq declarator ) compound-statement catch ( attr(optional) type-specifier-seq abstract-declarator(optional) ) compound-statement catch ( ... ) compound-statement

compound-statement

- the brace-enclosed sequence of statements that constututes the body of a function

attr(C++11) - optional list of attributes, applies to the formal parameter

type-specifier-seq

- part of a formal parameter declaration, same as in a function parameter list

declarator - part of a formal parameter declaration, same as in a function parameter list

abstract-declarator

- part of an unnamed formal parameter declaration, same as in function parameter list

1) Catch-clause that declares a named formal parameter

try { /* */ } catch(const std::exception& e) { /* */ }

2) Catch-clause that declares an unnamed parameter

try { /* */ } catch(const std::exception&) { /* */ }

3) Catch-all handler, which is activated for any exception

try { /* */ } catch(...) { /* */ }

You need to catch the exception by reference. &

try { f(); } catch(const std::overflow_error& e) { // this executes if f() throws std::overflow_error (same type

Page 191: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

191

rule) } catch(const std::runtime_error& e) { // this executes if f() throws std::underflow_error (base class rule) } catch(const std::exception& e) { // this executes if f() throws std::logic_error (base class rule) } catch(...) { // this executes if f() throws std::string or int or any other unrelated type }

arrange specific to general

try { // throws something } catch ( const MostSpecificException& e ) { // handle custom exception } catch ( const LessSpecificException& e ) { // handle custom exception } catch ( const std::exception& e ) { // standard exceptions } catch ( ... ) { // everything else }

Exceptions provide a way to react to exceptional circumstances (like runtime errors) in programs by transferring control to special functions called handlers.

To catch exceptions, a portion of code is placed under exception inspection. This is done by enclosing that portion of code in a try-block. When an exceptional circumstance arises within that block, an exception is thrown that transfers the control to the exception handler. If no exception is thrown, the code continues normally and all handlers are ignored.

An exception is thrown by using the throw keyword from inside the try block. Exception handlers are declared with the keyword catch, which must be placed immediately after the try block:

// exceptions #include <iostream> using namespace std; int main () {

An exception occurred. Exception Nr. 20

Page 192: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

192

try { throw 20; } catch (int e) {

cout << “An exception occurred. Exception Nr.” << e << ‘\n’; } return 0; }

The code under exception handling is enclosed in a try block. In this example this code simply throws an exception:

throw 20;

A throw expression accepts one parameter (in this case the integer value 20), which is passed as an argument to the exception handler.

The exception handler is declared with the catch keyword immediately after the closing brace of the try block. The syntax for catch is similar to a regular function with one parameter. The type of this parameter is very important, since the type of the argument passed by the throw expression is checked against it, and only in the case they match, the exception is caught by that handler.

Multiple handlers (i.e., catch expressions) can be chained; each one with a different parameter type. Only the handler whose argument type matches the type of the exception specified in the throw statement is executed.

If an ellipsis (...) is used as the parameter of catch, that handler will catch any exception no matter what the type of the exception thrown. This can be used as a default handler that catches all exceptions not caught by other handlers:

try { // code here } catch (int param) { cout <<

“int exception”; } catch (char

Page 193: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

193

param) { cout <<

“char exception”; } catch (...) { cout <<

“default exception”; }

In this case, the last handler would catch any exception thrown of a type that is neither int nor char.

A typical example where standard exceptions need to be checked for is on memory allocation:

int main () { try { int* myarray= new int[1000]; } catch (exception& e) {

cout << “Standard exception:” << e.what() << endl; } return 0; }

You Can create a base exception class and have all of your specific exceptions derive from it:

class BaseException { };

class HourOutOfRangeException : public BaseException { };

class MinuteOutOfRangeException : public BaseException { };

You can then catch all of them in a single catch block:

catch (const BaseException& e) { }

Base and Derived Class Exceptions and inheritance

Exam Question Since it’s possible to throw classes as exceptions, and classes can be derived from other classes, we need to consider what happens when we use inherited classes as exceptions. As it turns out, exception handlers will not only match classes of a specific type, they’ll also match classes derived from that specific type as well! Consider the following example:

Page 194: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

194

class Base { public: Base() {} }; class Derived: public Base { public: Derived() {} }; int main() { try { throw Derived(); } catch (Base &cBase) // Derived is derived from Base, Derived is-a Base {

cerr << “caught Base”; } catch (Derived &cDerived) {

cerr << “caught Derived”; } return 0; }

In the above example we throw an exception of type Derived. However, the output of this program is:

caught Base

What happened?

1. First, as mentioned above, derived classes will be caught by handlers for the base type.

Because Derived is derived from Base, Derived is-a Base (they have an is-a relationship).

2. Second, when C++ is attempting to find a handler for a raised exception, it does so sequentially.

Consequently, the first thing C++ does is check whether the exception handler for Base matches the Derived exception.

Because Derived is-a Base, the answer is yes, and it executes the catch block for type Base!

The catch block for Derived is never even tested in this case.

In order to make this example work as expected, we need to flip the order of the

Page 195: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

195

catch blocks:

class Base { public: Base() {} }; class Derived: public Base { public: Derived() {} }; int main() { try { throw Derived(); } catch (Derived &cDerived) {

cerr << “caught Derived”; } catch (Base &cBase) {

cerr << “caught Base”; } return 0; }

This way, the Derived handler will get first shot at catching objects of type Derived (before the handler for Base can). Objects of type Base will not match the Derived handler (Derived is-a Base, but Base is not a Derived), and thus will “fall through” to the Base handler.

Rule: Handlers for derived exception classes should be listed before those for base classes.

The ability to use a handler to catch exceptions of derived types using a handler for the base class turns out to be exceedingly useful.

Let’s take a look at this using std::exception. There are many classes derived from std::exception, such as std::bad_alloc, std::bad_cast, std::runtime_error, and others. When the standard library has an error, it can throw a derived exception correlating to the appropriate specific problem it has encountered.

Dynamic exception specification If the function throws an exception of the type not listed in its exception specification, the function std::unexpected is called. exam question

Page 196: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

196

exception specification The default function calls std::terminate, but it may be replaced by a user-provided function (via std::set_unexpected) which may call std::terminate or throw an exception.

If the exception thrown from std::unexpected is accepted by the exception specification, stack unwinding continues as usual. If it isn’t, but std::bad_exception is allowed by the exception specification, std::bad_exception is thrown. Otherwise, std::terminate is called.

Exception specifications C++11 Visual Studio 2013

They were designed to provide summary information about what exceptions can be thrown out of a function, but in practice they were found to be problematic. The one exception specification that did prove to be somewhat useful was the throw() specification.

For example:

void MyFunction(int i) throw();

Visual C++ departs from the ISO C++ Standard in its implementation of exception specifications. The following table summarizes the Visual C++ implementation of exception specifications:

throw() - Function does not throw an exception except explicitly with throw(), Visual C will not call unexpected

throw (type) - throw an exception of type

C++11 it’s been given its own keyword (noexcept)

The simple “good practice” tip is: don’t use exception specifications.

As for what happens when/if you do throw an exception of a type not allowed by the

exception specification:

std::unexpected() gets invoked then invokes terminate().

You can use std::set_unexpected to set your own handler -- but about all you can

reasonably do is add some logging before you terminate(). Your unexpected handler is not

allowed to return.

Page 197: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

197

Page 198: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

198

Shallow vs. deep copying

Shallow copying A shallow copy just copies the values of the data as they are.

Because C++ does not know much about your class, the default copy constructor and default assignment operators it provides use a copying method known as a shallow copy (also known as a memberwise copy). A shallow copy means that C++ copies each member of the class individually using the assignment operator. When classes are simple (eg. do not contain any dynamically allocated memory), this works very well.

For example, let’s take a look at our Cents class:

class Cents { private: int m_nCents; public: Cents(int nCents=0) { m_nCents = nCents; } };

Deep copying

The answer to this problem is to do a deep copy on any non-null pointers being copied. A deep copy duplicates the object or variable being pointed to so that the destination (the object being assigned to) receives it’s own local copy. This way, the destination can do whatever it wants to it’s local copy and the object that was copied from will not be affected. Doing deep copies requires that we write our own copy constructors and overloaded assignment operators.

Let’s go ahead and show how this is done for our MyString class:

// Copy constructor MyString::MyString(const MyString& cSource) { // because m_nLength is not a pointer, we can shallow copy it m_nLength = cSource.m_nLength; // m_pchString is a pointer, so we need to deep copy it if it is non-null if (cSource.m_pchString) { // allocate memory for our copy m_pchString = new char[m_nLength]; // Copy the string into our newly allocated memory strncpy(m_pchString, cSource.m_pchString, m_nLength); } else m_pchString = 0;

Page 199: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

199

}

Summary

The default copy constructor and default assignment operators do shallow copies, which is fine for classes that contain no dynamically allocated variables.

Classes with dynamically allocated variables need to have a copy constructor and assignment operator that do a deep copy.

The assignment operator is usually implemented using the same code as the copy constructor, but it checks for self-assignment, returns *this, and deallocates any previously allocated memory before deep copying.

If you don’t want a class to be copyable, use a private copy constructor and assignment operator prototype in the class header.

Page 200: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

200

Primitive Data Types

Standard Primitive Types

int

real

bool (boolean Java)

char

set

Page 201: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

201

Type conversions

Converting to int from some smaller integer type, or to double from float is known as promotion

Some of these conversions may imply a loss of precision

Pointer upcast (converting from pointer-to-derived to pointer-to-base)

Pointer downcast (convert from pointer-to-base to pointer-to-derived) polymorphic (callses with virtual members)

Explicit

Keyword explicit

explicit:

dynamic_cast

used with pointers and references to classes (or with void*).

reinterpret_cast

converts any pointer type to any other pointer type, even of unrelated classes.

also cast pointers to or from integer types

const_cast

manipulates the constness of the object pointed by a pointer, either to be set or to be removed

typeid

typeid allows to check the type of an expression:

Implicit Single-argument constructors:

allow implicit conversion from a particular type to initialize an object.

Assignment operator:

allow implicit conversion from a particular type on assignments.

Type-cast operator:

allow implicit conversion to a particular type.

Type-cast operator implicit

// implicit conversion of classes: #include <iostream> using namespace std;

Page 202: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

202

class A {}; class B { public: // conversion from A (constructor): // explicit prevents unintended results explicit B (const A& x) {} // conversion from A (assignment): B& operator= (const A& x) {return *this;} // conversion to A (type-cast operator) operator A() {return A();} }; int main () { A foo; B bar = foo; // calls constructor bar = foo; // calls assignment foo = bar; // calls type-cast operator return 0;

The type-cast operator uses a particular syntax: it uses the operator keyword followed by the destination type and an empty set of parentheses. Notice that the return type is the destination type and thus is not specified before the operator keyword.

Keyword explicit // explicit: #include <iostream> using namespace std; class A {}; class B { public: explicit B (const A& x) {} B& operator= (const A& x) {return *this;} operator A() {return A();} }; void fn (B x) {} int main () { A foo; B bar (foo); bar = foo; foo = bar; // fn (foo); // not allowed for explicit ctor. fn (bar); return 0; }

Type Cast operator explicit

dynamic_cast

used with pointers and references to classes (or with void*).

Page 203: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

203

// dynamic_cast #include <iostream> #include <exception> using namespace std; class Base { virtual void dummy() {} };

class Derived: public Base { int a; }; int main () { try { Base * pba = new Derived; Base * pbb = new Base; Derived * pd; pd = dynamic_cast<Derived*>(pba);

if (pd==0) cout << “Null pointer on first type-cast.\n”; pd = dynamic_cast<Derived*>(pbb);

if (pd==0) cout << “Null pointer on second type-cast.\n”;

} catch (exception& e) {cout << “Exception:” << e.what();} return 0; }

pba is pointing to a full object of class Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object of class Derived.

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes.

also cast pointers to or from integer types

const_cast manipulates the constness of the object pointed by a pointer, either to be set or to

be removed

// const_cast #include <iostream> using namespace std; void print (char * str) {

cout << str << ‘\n’; } int main () {

const char * c = “sample text”; print ( const_cast<char *> (c) ); return 0; }

typeid typeid allows to check the type of an expression:

typeid (expression)

This operator returns a reference to a constant object of type type_info that is defined in the standard header <typeinfo>. A value returned by typeid can be compared with another value returned by typeid using operators == and != or can serve to obtain a null-terminated character sequence representing the data type or

Page 204: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

204

class name by using its name() member.

// typeid #include <iostream> #include <typeinfo> using namespace std; int main () { int * a,b; a=0; b=0; if (typeid(a) != typeid(b)) {

cout << “a and b are of different types:\n”;

cout << “a is:” << typeid(a).name() << ‘\n’; cout << “b is:” << typeid(b).name() << ‘\n’; } return 0; }

OUTPUT

a and b are of different types: a is: int * b is: int

static_cast static_cast < new_type > ( expression )

converts between types using combination of implicit and user-defined conversions

new_type is

Temp(expression) say constructor

pointer to reference, downcast if necessary

rvalue reference type converts to xvalue or sub-object

void then discards the value of the expression after evaluating it

lvalue-to-rvalue, array to pointer or function to pointer

scoped enumeration to integer or float

int, float or enum converte to any enum, after c++17 rules will be defined

pointer to member of class D upcast to pointer to member of base class B

pointer to voide converted to pointer of any type

#include <vector> #include <iostream> struct B {}; struct D : B {}; enum class E { ONE, TWO, THREE }; enum EU { ONE, TWO, THREE }; int main() { // 1: initializing conversion int n = static_cast<int>(3.14);

Page 205: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

205

std::cout << “n = ” << n << ‘\n’; std::vector<int> v = static_cast<std::vector<int>>(10);

std::cout << “v.size() = “ << v.size() << ‘\n’; // 2: static downcast D d; B& br = d; // upcast via implicit conversion D& another_d = static_cast<D&>(br); // downcast // 3: lvalue to xvalue std::vector<int> v2 = static_cast<std::vector<int>&&>(v);

std::cout << “after move, v.size() = ” << v.size() << ‘\n’; // 4: discarded-value expression static_cast<void>(v2.size()); // 5. inverse of implicit conversion // todo // 6. array-to-pointer followed by upcast D a[10]; B* dp = static_cast<B*>(a); // 7. scoped enum to int or float E e = E::ONE; int one = static_cast<int>(e); // 8. int to enum, enum to another enum E e2 = static_cast<E>(one); EU eu = static_cast<EU>(e2); // 9. pointer to member upcast // todo // 10. void* to any type void* voidp = &e; std::vector<int>* p = static_cast<std::vector<int>*>(voidp); } Output: n = 3 v.size() = 10 after move, v.size() = 0

Page 206: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

206

std::string - the C++ String Class

By Alex Allain

C++ provides a simple, safe alternative to using char*s to handle strings. The C++ string class, part of the std namespace, allows you to manipulate strings safely.

Declaring a string is easy:

using namespace std; string my_string;

or

std::string my_string;

You can also specify an initial value for the string in a constructor:

using namespace std;

string my_string(“starting value”);

String I/O is easy, as strings are supported by cin.

cin>>my_string;

If you need to read an entire line at a time, you can use the getline function and pass in an input stream object (such as cin, to read from standard input, or a stream associated with a file, to read from a file), the string, and a character on which to terminate input. The following code reads a line from standard input (e.g., the keyboard) until a newline is entered.

using namespace std;

getline(cin, my_string, ‘\n’);

String concatenation Strings can also be assigned to each other or appended together using the + operator:

string my_string1 = “a string”; string my_string2 = “is this”; string my_string3 = my_string1 + my_string2;

// Will ouput a string is this” cout<<my_string3<<endl;

Naturally, the += operator is also defined! String concatenation will work as long as either of the two strings is a C++ string--the other can be a static string or a char*.

String Comparisons One of the most confusing parts of using char*s as strings is that comparisons are tricky, requiring a special comparison function, and using tests such as == or < don’t mean what you’d expect. Fortunately, for C++ strings, all of the typical relational operators work as expected to compare either C++ strings or a C++ string and either a C string or a static string (i.e.,”one in quotes”).

For instance, the following code does exactly what you would expect, namely, it determines whether an input string is equal to a fixed string:

Page 207: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

207

string passwd;

getline(cin, passwd, ‘\n’); if(passwd ==“xyzzy”) { cout<<“Access allowed”; }

String Length and Accessing Individual Elements To take the length of a string, you can use either the length or size function, which are members of the string class, and which return the number of characters in a string:

string my_string1 = ten chars.; int len = my_string1.length(); // or .size();

Strings, like C strings (char*s), can be indexed numerically. For instance, you could iterate over all of the characters in a string indexing them by number, as though the the string were an array.

Note that the use of the length() or size() function is important here because C++ strings are not guaranteed to be null-terminated (by a ‘\0’). (In fact, you should be able to store bytes with a value of 0 inside of a C++ string with no adverse effects. In a C string, this would terminate the string!)

int i; for(i = 0; i < my_string.length(); i++) { cout<<my_string[i]; }

On the other hand, strings are actually sequences, just like any other STL container, so you can use iterators to iterate over the contents of a string.

string::iterator my_iter; for(my_iter = my_string.begin(); my_iter != my_string.end(); my_iter++) { cout<<*my_iter; }

Note that my_string.end() is beyond the end of the string, so we don’t want to print it, whereas my_string.begin() is at the first character of the string.

Incidentally, C++ string iterators are easily invalidated by operations that change the string, so be wary of using them after calling any string function that may modify the string.

Searching and Substrings The string class supports simple searching and substring retrieval using the functions find(), rfind(), and substr(). The find member function takes a string and a position and begins searching the string from the given position for the first occurence of the given string. It returns the position of the first occurence of the string, or a special value, string::npos, that indicates that it did not find the substring.

This is what the find function prototype would look like. (Note that I’ve used ints here for clarity, but they would actually be of the type “size_type”, which is unsigned.)

int find(string pattern, int position);

Page 208: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

208

This sample code searches for every instance of the string “cat” in a given string and counts the total number of instances:

string input; int i = 0; int cat_appearances = 0;

getline(cin, input, ‘\n’);

for(i = input.find(“cat”, 0); i != string::npos; i = input.find(“cat”, i)) { cat_appearances++; i++; // Move past the last discovered instance to avoid finding same // string } cout<<cat_appearances;

Similarly, it would be possible to use rfind in almost the exact same way, except that searching would begin at the very end of the string, rather than the beginning. (String matches would still be from left-to-right--that is, it wouldn’t match “cat” with a string containing “tac”.) How would you need to modify the above program to use rfind?

On the other hand, the substr function can be used to create a new string consisting only of the slice of the string beginning at a given position and of a particular length:

// sample prototype string substr(int position, int length);

For instance, to extract the first ten characters of a string, you might use

string my_string = “abcdefghijklmnop”; string first_ten_of_alphabet = my_string.substr(0, 10); cout<<“The first ten letters of the alphabet are” <<first_ten_of_alphabet;

Modifying Strings via Splicing or Erasure It’s also possible to modify C++ strings to either remove part of a string or add in new text. The erase() function looks very similar to substr in its prootype; it takes a position and a character count and removes that many characters starting from the given position. Note that position is zero-indexed, as usual.

string my_removal = “remove aaa”; my_removal.erase(7, 3); // erases aaa

To delete an entire string, you could use

str.erase(0, str.length());

On the other hand, you can also splice one string into another. The member function insert takes a position and a string and inserts that string starting at the given position:

string my_string = “ade”; my_string.insert(1, “bc”); // my_string is now “abcde” cout<<my_string<<endl;

String concatenation can be implemented in terms of insert, using the position past the last element of the string as the insertion point (i.e., the str.length()). Trying to insert beyond the length of the string will result in a segmentation fault.

Page 209: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

209

Copying vs. Sharing Because strings are mutable (they can change what they hold), it is important to know whether strings are copied or share the same memory. (This matters if, for instance, you pass a string to a function that modifies the string--does it also modify the string passed in to the function because they share the same memory storing the actual string?) It turns out that, in effect, they are copied, but in practice, it’s possible that your implementation may delay copying until absolutely necessary. As a result, some operations you might expect to be slow, such as passing a large string to a function, may turn out to be faster than expected. Of course, before you rely on this behavior, you should check your implementation to make sure that it delays copies when not necessary.

Retrieving a c-style string (char*) Sometimes it can be useful to retrieve a char* from a C++ string. This might be necessary for use with a particular C standard library function that takes a char*, or for compatibility with older code that expects a char* rather than a C++ string. The string member function c_str() will return the string in the form of a char* (with a null-terminator).

// The prototype: const char* c_str(); // usage example string my_string = x; cout<<strlen(my_string.c_str());

Notice that the returned char* is a const value; you should not try to modify this string (it is read-only), and you do not need to free/delete it. Doing so is an error. If you need to modify the char*, you should create a second string and use the strcpy function to duplicate the result of calling c_str().

std::basic_string

Although the string class is useful, it may not suit your needs for internationalization. In particular, if you need support for a different character set or wide characters, you may want something a bit different. For this, you can take advantage of the basic_string template, from which string itself is derived.

typedef basic_string<char> string;

If you need to use a string with, say, wide characters, you can declare a basic string to store the sequence of characters:

basic_string<wchar_t> wide_char_str; // or even just basic_string<unsigned char> u_char_str;

This, too, can be simplified using typedef:

typedef basic_string<unsigned char> ustring;

Page 210: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

210

Operator Overloading

You can overload most of the built-in operators available in C++. Thus a programmer can use operators with user-defined types as well.

Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.

Box operator+(const Box&);

declares the addition operator that can be used to add two Box objects and returns final Box object. Most overloaded operators may be defined as

4. ordinary non-member functions or as

5. class member functions.

In case we define above function as non-member function of a class then we would have to pass two arguments for each operand as follows:

Box operator+(const Box&, const Box&);

Following is the example to show the concept of operator over loading using a member function. Here an object is passed as an argument whose properties will be accessed using this object, the object which will call this operator can be accessed using this operator as explained below:

#include <iostream> using namespace std; class Box { public: double getVolume(void) { return length * breadth * height; } void setLength( double len ) { length = len; } void setBreadth( double bre ) { breadth = bre; } void setHeight( double hei ) { height = hei; } // Overload + operator to add two Box objects. Box operator+(const Box& b) { Box box;

Page 211: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

211

box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Main function for the program int main( ) { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box Box Box3; // Declare Box3 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // box 2 specification Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // volume of box 1 volume = Box1.getVolume();

cout << “Volume of Box1 :” << volume <<endl; // volume of box 2 volume = Box2.getVolume();

cout << “Volume of Box2 :” << volume <<endl; // Add two object as follows: Box3 = Box1 + Box2; // volume of box 3 volume = Box3.getVolume();

cout << “Volume of Box3 :” << volume <<endl; return 0; }

When the above code is compiled and executed, it produces the following result:

Volume of Box1 : 210 Volume of Box2 : 1560 Volume of Box3 : 5400

Overloadable/Non-overloadableOperators:

Following is the list of operators which can be overloaded: + - * / % ^

Page 212: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

212

& | ~ ! , =

< > <= >= ++ --

<< >> == != && ||

+= -= /= %= ^= &=

|= *= <<= >>= [] ()

-> ->* new new [] delete delete []

Following is the list of operators, which can not be overloaded:

:: .* . ?:

Operator Overloading Examples: Here are various operator overloading examples to help you in understanding the concept. S.N. Operators and Example

1 Unary operators overloading

2 Binary operators overloading

3 Relational operators overloading

4 Input/Output operators overloading

5 ++ and -- operators overloading

6 Assignment operators overloading

7 Function call () operator overloading

8 Subscripting [] operator overloading

9 Class member access operator -> overloading

There are various relational operators supported by C++ language like (<, >, <=, >=, ==, etc.) which can be used to compare C++ built-in data types.

You can overload any of these operators, which can be used to compare the objects of a class.

Following example explains how a < operator can be overloaded and similar way you can overload other relational operators.

#include <iostream>

using namespace std;

class Distance { private: int feet; // 0 to infinite int inches; // 0 to 12 public: // required constructors Distance(){ feet = 0; inches = 0; } Distance(int f, int i){ feet = f; inches = i; } // method to display distance

Page 213: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

213

void displayDistance() { cout << “F:” << feet << “ I:” << inches <<endl; } // overloaded minus (-) operator Distance operator- () { feet = -feet; inches = -inches; return Distance(feet, inches); } // overloaded < operator bool operator <(const Distance& d) { if(feet < d.feet) { return true; } if(feet == d.feet && inches < d.inches) { return true; } return false; } }; int main() { Distance D1(11, 10), D2(5, 11); if( D1 < D2 ) //calls overloaded operator < { cout << “D1 is less than D2” << endl; } else { cout << “D2 is less than D1” << endl; } return 0; }

When the above code is compiled and executed, it produces the following result:

D2 is less than D1

Which operator to overload in order to access container std::set<Value>?

class Value { std::string sval; int i_val; public: Value(std:string s, inti i) : s_val(s), i_val(i) {} };

You need to implement operator< for your type. Associateive containers map, set,

Page 214: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

214

require that the ordering of elements must follow Strict Weak Ordering, which means your implementation of operator< must follow strict weak ordering

bool operator<(string& x, int y){…}

Q- Overload operator ++ both prefix and postfix

The difference lies in what signature you choose for your overload(s) of operator ++.

class Number { public: Number& operator++ (); // ++ prefix: no parameter, returns a reference Number operator++ (int); // postfix ++: dummy parameter, returns a value };

A- You have two ways to overload the two (prefix/postfix) ++ operators for a type T:

Object method:

This is the easiest way, using “common” OOP idiom.

class T { public : T & operator++() // ++A { // Do increment of “this” value return *this ; } T operator++(int) // A++ { T temp = *this ; // Do increment of “this” value return temp ; } } ;

Object non-member function:

This is another way to do this: As long as the functions are in the same namespace as the object they are referring too, they will be considered when the compiler will search for a fonction to handle ++t ; or t++ ; code:

class T { // etc. } ; T & operator++(T & p_oRight) // ++A { // Do increment of p_oRight value

Page 215: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

215

return p_oRight ; } T operator++(T & p_oRight, int) // A++ { T oCopy ; // Copy p_oRight into oCopy // Do increment of p_oRight value return oCopy ; }

non-member functions are still part of T’s interface (as long as they are in the same namespace).

There are two potential advantages of the non-member function notation:

If you manage to code them without making them friend of T, then you increased the encapsulation of T

you can apply this even to classes or structures whose code you don’t own. This is a non-intrusive way to enhance the interface of an object without modifying its declaration.

Page 216: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

216

Function overloading in C++: You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You can not overload function declarations that differ only by return type.

Following is the example where same function print() is being used to print different data types:

#include <iostream>

using namespace std;

class printData

{

public:

void print(int i) {

cout << “Printing int:” << i << endl;

}

void print(double f) {

cout << “Printing float:” << f << endl;

}

void print(char* c) {

cout << “Printing character:” << c << endl;

}

};

int main(void)

{

printData pd;

// Call print to print integer

pd.print(5);

// Call print to print float

pd.print(500.263);

// Call print to print character

pd.print(“Hello C++”);

return 0;

}

When the above code is compiled and executed, it produces the following result:

Printing int: 5

Printing float: 500.263

Printing character: Hello C++

Page 217: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

217

Loops

do

do { std::cout <<“do “<< f<< endl;} while (++f < 10) ; // 0-9

pre-increment then eval

do { std::cout <<“do”<< f<< endl;} while (f++ < 10) ; // 0-10

eval then post-increment

Page 218: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

218

for for (INITIALIZER; CONDITION to control loop; iteration of variable) {

do_stuff();

}

can be written as

INITIALIZER;

while(CONDITION) {

do_stuff();

OPERATION;

}

++i pre-increment, i++ post-increment

++i increments i and eval to the new val of i

i++ eval and increment i

for loop this doesn’t matter.

for (int i = 0; I < 5; i++) { } // 0,1,2

is basically

int i = 0;

while(i < 5) {

printf(“%d”, i); i++;

}

and

for (int i = 0; i < 5; ++i) { } // 0,1,2

is basically

int i = 0;

while(i < 5) {

printf(“%d”, i); ++i;

}

Note that the lines i++; and ++i; have the same semantics FROM THE PERSPECTIVE OF

THIS BLOCK OF CODE. They both have the same effect on the value of i (increment it by

one) and therefore have the same effect on the behavior of these loops.

Page 219: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

219

Note that there would be a difference if the loop was rewritten as

int i = 0;

int j = i;

while(j < 5) {

printf(“%d”, i);

j = ++i; //j sees the value of i after the increment (i is incremented

first, }

int i = 0;

int j = i;

while(j < 5) {

printf(“%d”, i);

j = i++; // j sees the value of i before the increment. }

This is because in first block of code j sees the value of i after the increment (i is incremented first, or pre-incremented, hence the name) and in the second block of code j sees the value of i before the increment.Three reasons why you should pre-increment:

1. You won’t have to think about whether the variable/object might have an overloaded post-incrementation method (for example in a template function) and treat it differently (or forget to treat it differently).

2. Consistent code looks better. 3. When someone asks you “Why do you pre-increment?” you’ll get the chance to

teach them about the halting problem and theoretical limits of compiler optimization. :)

Also you can do this in for loops

for ( n=0, i=100; n!=i; ++n, --i)

both initialized

one condition

both incremented or decremented inside loop

Page 220: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

220

while int n = 10;

while (n>0) {

cout << n << “,”; --n;

}

int b = 0; while (b++ < 10) // 1-10 increments after eval eval expression before post-increment increment print 0<10, increment to 1, print 1 9<10, increment to 10, print 10 10<10 exit //while (++b < 10) // 1-9 increments before eval increment eval expression after pre-increment print 1<10, print 1 9<10, print 9 10<10 exit

Page 221: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

221

Input/Output Library

C++ includes two input/output libraries: a modern, stream-based I/O library and the standard set of C-style I/O functions.

Stream-based I/O The stream-based input/output library is organized around abstract input/output devices.

Separate typedefs are provided for the most common basic character types (char and wchar_t). The classes are organized into the following hierarchy:

Detailed class definitions (all in namespace std) basic_iostream<> : Defines objects that can be used for both reading and writing.

basic_streambuf<>: The heart of the iostream library. Defines interface to all representations that can be written to or read from by streams. Used by other stream classes to do the actual reading/writing of characters.

template<class charT, class traits = char_traits<charT> > class basic_streambuf;

typedef basic_streambuf<char> streambuf;

typedef basic_streambuf<wchar_t> wstreambuf;

template< ... > class basic_istream;

Page 222: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

222

template< ... > class basic_ostream;

template< ... > class basic_iostream;

typedef basic_istream<char> istream;

typedef basic_istream<wchar_t> wistream;

Page 223: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

223

C++ Standard Library Header Files

Visual Studio 2013

Algorithms <algorithm>

Containers Sequence

<array> , <deque>, <forward_list>, <list>, <vector>

Ordered Associative

<map> , <set>

Unordered Associative

<unordered_map> , <unordered_set>

Adaptor

<queue> , <stack>

Input/Output <filesystem> , <fstream>, <iomanip>, <ios>, <iosfwd>, <iostream>, <istream>, <ostream>, <sstream>, <streambuf>, <strstream>

Iterators Library <iterator>

Other Utilities <bitset> , <chrono>, <initializer_list>, <tuple>, <type_traits>, <typeinfo>,

<typeindex>, <utility>

<functional> tons of functions, binds, binary, const, greater than, less than, memory, etc.

bind1st

bind2nd

1. take a binary function along with one of the

2. parameters and

3. bind it in a function object.

4. This function object will be then a unary function. #include <functional> vector<int>::iterator::difference_type result1a; count_if(InputIterator first, InputIterator last, Predicate pred) result1a = count_if(v1.begin(), v1.end(), bind2nd(std::greater<int>(), 10)); // Count the number of integers > 10 in the vector

Page 224: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

224

// iterating through vector // function object (functor) greater functor and bind the second argument 10 to it, // producing a unary functor that compares its input to the value 10. // If greater than 10, then true and count_if increments by one. std::replace_if(start, end, std::bind2nd(std::less(int)), 10); std::replace_if( start, end, accept element from range returns True / False, replace with this value) std::bind2nd(std::less(int)) test if value less than 10 if true condition replace value with 10 additional argument difference

std::replace_if(start, end, std::bind2nd(std::less<int>, 5), 5); if values in vector less than 5 replace with 5

The output is

6 2 9 4 7

6 5 9 5 7

std::less<int>() for ascending order std::greater<int>() for descending order

also

replace

void replace(ForwardIt first, ForwardIt last, const T& old_value, const T& new_value)

Functor = function predicate specific function or functor

bool check if need to perform specific function or not

1) returns a boolean

2) Cannot modify data

Class NeedCopy{ bool operator()(int x){ return (x>20) !! (x<5); } transform(myset.begin(), myset.end()src back_inserter(d), dest NeedCopy() predicate

Transform uses predicate to determine if need to copy or not

Page 225: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

225

create a functor AddValue

class Addvalue { int val; public: AddValue(int j):val(j) {} //constructor initialize fal w/value of j; void operator() (init i) { cout << itval << endl; }

main vector <int> vec = {2,3,4,5}; foreach(vec.begin(), vec.end(), AddValue(x)<x>); // output {4,5,6,7)

bulit in functors

less

greater

greater_equal

not equal

logical

multiples

plus

divide, etc

Page 226: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

226

C++ Operator Precedence

The following table lists the precedence and associativity of C++ operators. Operators are listed top to bottom, in descending precedence.

Precedence

Operator Description Associativity

1 :: Scope resolution

Left-to-right

2

++ --

Suffix/postfix increment and decrement

type() type{} Function-style type cast

() Function call

[] Array subscripting

. Element selection by reference

->

Element selection through pointer

3

++ --

Prefix increment and decrement

Right-to-left

+ - Unary plus and minus

! ~ Logical NOT and bitwise NOT

(type) C-style type cast

* Indirection (dereference)

& Address-of

sizeof Size-of[note 1]

new, new[] Dynamic memory allocation

delete, delete[]

Dynamic memory deallocation

4 .* ->* Pointer to member

Left-to-right

5 * / %

Multiplication, division, and remainder

6 + - Addition and subtraction

7 << >> Bitwise left shift and right shift

Page 227: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

227

8

< <=

For relational operators < and ≤ respectively

> >=

For relational operators > and ≥ respectively

9 == !=

For relational = and ≠ respectively

10 & Bitwise AND

11 ^ Bitwise XOR (exclusive or)

12 | Bitwise OR (inclusive or)

13 && Logical AND

14 || Logical OR

15

?: Ternary conditional

[n

ote 2]

Right-to-left

=

Direct assignment (provided by default for C++ classes)

+= -= Assignment by sum and difference

*= /= %=

Assignment by product, quotient, and remainder

<<= >>=

Assignment by bitwise left shift and right shift

&= ^= |=

Assignment by bitwise AND, XOR, and OR

16 throw

Throw operator (for exceptions)

17 , Comma Left-to-right

1. ↑ The operand of sizeof can’t be a C-style type cast: the expression sizeof

(int) * p is

Page 228: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

228

Functions with Variable Argument Lists in C++

variable argument list (va_list).

macros/functions va_start, va_arg, va_end to allow to pass variable number of arguments to its functions.

Step 1. We will prepare a function to take variable number of arguments. So, the function signature should be like this:

function_name(variable_type variable_name, …);

The second argument is an ellipse (three dots); which tells the compiler, through this function we are passing variable number of arguments.

ex

void varargs_fn(int num, … );

Page 229: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

229

Multithread, Multi-Thread, Semaphore, lock, mutex, etc see separate document

Page 230: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

230

Socket A socket is a resource assigned to the server process.

There are several different types of socket that determine the structure of the transport layer. The most common types are stream sockets and datagram sockets.

Stream Sockets Stream sockets provide reliable two-way communication similar to when we call someone on the phone. One side initiates the connection to the other, and after the connection is established, either side can communicate to the other. In addition, there is immediate confirmation that what we said actually reached its destination. Stream sockets use a Transmission Control Protocol (TCP), which exists on the transport layer of the Open Systems Interconnection (OSI) model. The data is usually transmitted in packets. TCP is designed so that the packets of data will arrive without errors and in sequence. Webservers, mail servers, and their respective client applications all use TCP and stream socket to communicate.

Datagram Sockets Communicating with a datagram socket is more like mailing a letter than making a phone call. The connection is one-way only and unreliable. If we mail several letters, we can’t be sure that they arrive in the same order, or even that they reached their destination at all. Datagram sockets use User Datagram Protocol (UDP). Actually, it’s not a real connection, just a basic method for sending data from one point to another. Datagram sockets and UDP are commonly used in networked games and streaming media.

Page 231: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

231

Header Files #include syntax user and system header files use #include

#include

#include has two variants

1. #include <myheader.h>

system header files, search standard list of system directories

2. #include “myheader.h”

user header files, your own program

searches first in current directory, then in quote directories then

header files

1. Absolute path name #include “/root/workingdirectory/first.h”

2. Relative paths: #include “../stdafx.h” #include “../shapes/sphere.h”

3. or add your project directory to your compiler include path and reference them like normal:

#include “stdafx.h” #include “shapes/sphere.h”

4. in makefile INCLUDE=-I/usr/include/freetype2

For gcc it is the -I option for header includes.

g++ -I/root/workingdirectory -I/root/workingdirectory2

Page 232: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

232

Input/Output with files

class istream - object cin and class ostream - object cout

ofstream: Stream class to write on files

open member function, default ios::out

ostream: Sub class

write for binary files

ifstream: Stream class to read from files

open member function, default ios::in

istream: Sub class

read for binary files

fstream: Stream class to both read and write from/to files.

open member function, default ios::in | ios::out

read and write for binary files

myfile.open (“filename”, mode);

write (memory_block, size);

read (memory_block, size);

ios::beg offset counted from the beginning of the stream

ios::cur offset counted from the current position

ios::end offset counted from the end of the stream

write to text file #include <iostream> #include <fstream> using namespace std; int main () { ofstream myfile; if (myfile.is_open()) { myfile.open (“example.txt”, ios::out); myfile << “Writing this to a file.\n”; myfile << “This is another line.\n”; myfile.close(); } return 0; } // ofstream myfile; // myfile.open (example.txt, ios::out); //constructor ofstream myfile (“example.bin”, ios::out);

Page 233: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

233

check if open if (myfile.is_open()) { /* ok, proceed with output */ }

close file myfile.close();

read from text file #include <iostream> #include <fstream> #include <string> using namespace std; int main () { string line; ifstream myinputfile (“example.txt”); if (myinputfile.is_open()) { while ( getline (myinputfile, line) ) {

cout << line << ‘\n’; } myinputfile.close(); } else cout << “Unable to open file”; return 0; }

reading an entire binary file #include <iostream> #include <fstream> using namespace std; int main () { streampos size; char * memblock; ifstream file (“example.bin”, ios::in|ios::binary|ios::ate); if (file.is_open()) { size = file.tellg(); // how big, size?? memblock = new char [size]; // request this amount of size file.seekg (0, ios::beg); // get position at beginning of file

Page 234: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

234

file.read (memblock, size); file.close(); cout << “the entire file content is in memory”; delete[] memblock; } else cout << “Unable to open file”; return 0; }

Page 235: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

235

Practice Programs

Dec_Binary_Conversion

Factorial

File_Size_Challenge

String_Permutation_Challenge

Int_English_string

Line_count_challenge

Page 236: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

236

Appendix

Priority Queue implentation with Array class PriorityQueue { private ComparisonKey[] A = new ComparisonKey[100]; // int -> CK private int next; PriorityQueue() { next = 0; } public void insert(ComparisonKey x) { // int -> CK A[next] = x; next++; } public ComparisonKey remove() { // int -> CK ComparisonKey high = A[0]; // int -> CK int highLoc = 0; for (int cur = 1; cur < next; cur++) { if (high.compareTo(A[cur]) == ComparisonKey.LOWER) { // use compareTo method! high = A[cur]; highLoc = cur; } } A[highLoc] = A[next-1]; next--; return high; } }

Stack Implementation with Class and Array #include <iostream> using namespace std; #define MAX 10 // MAXIMUM STACK CONTENT class stack { private: int arr[MAX]; // Contains all the Data int top; //Contains location of Topmost Data pushed onto Stack public: stack() //Constructor { top=-1; //Sets the Top Location to -1 indicating an empty stack } void push(int a) // Push ie. Add Value Function { top++; // increment to by 1 if(top<MAX) { arr[top]=a; //If Stack is Vacant store Value in Array }

Page 237: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

237

else {

cout<<“STACK FULL!!”<<endl; top--; } } int pop() // Delete Item. Returns the deleted item { if(top==-1) {

cout<<“STACK IS EMPTY!!!”<<endl; return NULL; } else { int data=arr[top]; //Set Topmost Value in data

Queue Implentation with Class and Array #include <iostream> using namespace std; #define MAX 5 // MAXIMUM CONTENTS IN QUEUE class queue { private: int t[MAX]; int al; // Addition End int dl; // Deletion End public: queue() { dl=-1; al=-1; } void del() { int tmp; if(dl==-1) {

cout<<“Queue is Empty”; } else { for(int j=0;j<=al;j++) { if((j+1)<=al) { tmp=t[j+1]; t[j]=tmp; } else { al--; if(al==-1) dl=-1;

Page 238: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

238

else dl=0; } } } } void add(int item) { if(dl==-1 && al==-1) { dl++; al++; } else { al++; if(al==MAX) {

cout<<“Queue is Full\n”; al--; return; } } t[al]=item; } void display() { if(dl!=-1) { for(int iter=0 ; iter<=al ; iter++)

cout<<t[iter]<< “ ”; } else

cout<<“EMPTY”; } }; int main() { queue a; int data[5]={32,23,45,99,24};

cout<<“Queue before adding Elements:”; a.display(); cout<<endl<<endl; for(int iter = 0 ; iter < 5 ; iter++) { a.add(data[iter]);

cout<<“Addition Number : ” <<(iter+1)<< “:”; a.display(); cout<<endl; } cout<<endl;

cout<<“Queue after adding Elements: ”; a.display(); cout<<endl<<endl; for(iter=0 ; iter < 5 ; iter++) { a.del();

cout<<“Deletion Number : “<<(iter+1)<<“ : ”;

Page 239: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

239

a.display(); cout<<endl; } return 0; }

Linked List Imp Class ptr to next Class #include <iostream> using namespace std; class linklist { private: struct node { int data; node *link; }*p; public: linklist(); void append( int num ); void add_as_first( int num ); void addafter( int c, int num ); void del( int num ); void display(); int count(); ~linklist(); }; linklist::linklist() { p=NULL; } void linklist::append(int num) { node *q,*t; if( p == NULL ) { p = new node; p->data = num; p->link = NULL; } else { q = p; while( q->link != NULL ) q = q->link; t = new node; t->data = num; t->link = NULL; q->link = t; } } void linklist::add_as_first(int num) { node *q;

Page 240: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

240

q = new node; q->data = num; q->link = p; p = q; } void linklist::addafter( int c, int num) { node *q,*t; int i; for(i=0,q=p;i<c;i++) { q = q->link; if( q == NULL ) {

cout<<“\nThere are less than “<<c<<“ elements.”; return; } } t = new node; t->data = num; t->link = q->link; q->link = t; } void linklist::del( int num ) { node *q,*r; q = p; if( q->data == num ) { p = q->link; delete q; return; } r = q; while( q!=NULL ) { if( q->data == num ) { r->link = q->link; delete q; return; } r = q; q = q->link; }

cout<<“\nElement “<<num<<“ not Found.”; } void linklist::display() { node *q; cout<<endl; for( q = p ; q != NULL ; q = q->link ) cout<<endl<<q->data; } int linklist::count() { node *q;

Page 241: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

241

int c=0; for( q=p ; q != NULL ; q = q->link ) c++; return c; } linklist::~linklist() { node *q; if( p == NULL ) return; while( p != NULL ) { q = p->link; delete p; p = q; } } int main() { linklist ll;

cout<<“No. of elements =” <<ll.count(); ll.append(12); ll.append(13); ll.append(23); ll.append(43); ll.append(44); ll.append(50); ll.add_as_first(2); ll.add_as_first(1); ll.addafter(3,333); ll.addafter(6,666); ll.display();

cout<<“\nNo. of elements = “<<ll.count(); ll.del(333); ll.del(12); ll.del(98);

cout<<“\nNo. of elements = “<<ll.count(); return 0; }

Stack Implementation

Linked List use when size and shape of data structure cannot be predicted in advance

dynamic data structure, second choice would be array.

ex of uses lists, stacks, queues, sets, trees, tables, heap

ex linked list of books

1) Define a class to rep each element/book

class Book

title

Page 242: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

242

pages

2) Define a class to rep list itself

class Booklist

link to first element

num of elements in list

3) Linked List operations

insertatfront (book node)

insertAtEnd (book node)

deleteFirst ()

printList();

4) consider search, insert, delete run time, memory usage vs other implentations

5) other data structures could be used, doubly linked list, tree

Binary Trees in C++

Insert function generally a recursive function that continues moving down the levels of a binary tree until there is an unused leaf in a position which follows the rules of placing nodes.

Rules: Descend tree,

If empty (NULL pointer from parent leaf)

Create node and store value and key value

Else IF /* node filled

key value to be inserted is less than the key value of the current node,

if left or right child node exists

recursive call on the left child node, works way back up

Else IF

key value to be inserted is greater than or equal to the key value of the current node

if left or right child node exists

recursive call on the right child node. Works way back up

Delete function: Descend tree If not NULL, Compare child(ren), descend left using smallest,

Null stop deletes the leftmost node, then the right child node from the leftmost node’s parent node, then it deletes the parent node,

Recursive part then works its way back up

In the example tree above, the order of deletion of nodes would be 5 8 6 11 18 14 10. Note that it is necessary to delete all the child nodes to avoid wasting memory.

Because binary trees have log (base 2) n layers, the average search time for a binary tree is log (base 2) n. To fill an entire binary tree, sorted, takes roughly log (base 2) n * n.

Page 243: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

243

Let’s take a look at the necessary code for a simple implementation of a binary tree.

Binary Tree implemented in C++

Header file //--------------------------------------------------------------- // File: B_Tree.h // Purpose: Header file for a demonstration of a binary tree // Programming Language: C++ // Author: Dr. Rick Coleman //--------------------------------------------------------------- #ifndef B_TREE_H #define B_TREE_H #include <iostream> using namespace std; // Define a structure to be used as the tree node struct TreeNode { int Key; float fValue; int iValue; char cArray[7]; TreeNode *left; TreeNode *right; }; class B_Tree { private: TreeNode *root; public: B_Tree(); ~B_Tree(); bool isEmpty(); TreeNode *SearchTree(int Key); int Insert(TreeNode *newNode); int Insert(int Key, float f, int i, char *cA); int Delete(int Key); void PrintOne(TreeNode *T); void PrintTree(); private: void ClearTree(TreeNode *T); TreeNode *DupNode(TreeNode * T); void PrintAll(TreeNode *T); }; #endif

Page 244: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

244

(.cpp) //--------------------------------------------------------------- // File: B_Tree.c // Purpose: Implementation file for a demonstration of a binary tree // Programming Language: C++ // Author: Dr. Rick Coleman // Date: February, 2002 //--------------------------------------------------------------- #include <iostream> #include <string.h>

#include “B_Tree.h” using namespace std; //-------------------------------------------- // Function: B_Tree() // Purpose: Class constructor. //-------------------------------------------- B_Tree::B_Tree() { root = NULL; return; } //-------------------------------------------- // Function: B_Tree() // Purpose: Class destructor. //-------------------------------------------- B_Tree::~B_Tree() { ClearTree(root); return; } //-------------------------------------------- // Function: ClearTree() // Purpose: Perform a recursive traversal of // a tree destroying all nodes. //-------------------------------------------- void B_Tree::ClearTree(TreeNode *T) { if(T==NULL) return; // Nothing to clear if(T->left != NULL) ClearTree(T->left); // Clear left sub-tree if(T->right != NULL) ClearTree(T->right); // Clear right sub-tree delete T; // Destroy this node return; } //-------------------------------------------- // Function: isEmpty() // Purpose: Return TRUE if tree is empty. //-------------------------------------------- bool B_Tree::isEmpty() { return(root==NULL); }

Page 245: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

245

//-------------------------------------------- // Function: DupNode() // Purpose: Duplicate a node in the tree. This // is used to allow returning a complete // structure from the tree without giving // access into the tree through the pointers. // Preconditions: None // Returns: Pointer to a duplicate of the node arg //-------------------------------------------- TreeNode *B_Tree::DupNode(TreeNode * T) { TreeNode *dupNode; dupNode = new TreeNode(); *dupNode = *T; // Copy the data structure dupNode->left = NULL; // Set the pointers to NULL dupNode->right = NULL; return dupNode; } //-------------------------------------------- // Function: SearchTree() // Purpose: Perform an iterative search of the tree and // return a pointer to a TreeNode containing the // search key or NULL if not found. // Preconditions: None // Returns: Pointer to a duplicate of the node found //-------------------------------------------- TreeNode *B_Tree::SearchTree(int Key) { int ValueInTree = false; TreeNode *temp; temp = root; while((temp != NULL) && (temp->Key != Key)) { if(Key < temp->Key) temp = temp->left; // Search key comes before this node. else temp = temp->right; // Search key comes after this node } if(temp == NULL) return temp; // Search key not found else return(DupNode(temp)); // Found it so return a duplicate } //-------------------------------------------- // Function: Insert() // Insert a new node into the tree. // Preconditions: None // Returns: int (TRUE if successful, FALSE otherwise) //-------------------------------------------- int B_Tree::Insert(TreeNode *newNode) { TreeNode *temp; TreeNode *back; temp = root; back = NULL; while(temp != NULL) // Loop till temp falls out of the tree { back = temp; if(newNode->Key < temp->Key) temp = temp->left; else

Page 246: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

246

temp = temp->right; } // Now attach the new node to the node that back points to if(back == NULL) // Attach as root node in a new tree root = newNode; else { if(newNode->Key < back->Key) back->left = newNode; else back->right = newNode; } return(true); } //-------------------------------------------- // Function: Insert() // Insert a new node into the tree. // Preconditions: None // Returns: int (TRUE if successful, FALSE otherwise) //-------------------------------------------- int B_Tree::Insert(int Key, float f, int i, char *cA) { TreeNode *newNode; // Create the new node and copy data into it newNode = new TreeNode(); newNode->Key = Key; newNode->fValue = f; newNode->iValue = i; strcpy(newNode->cArray, cA); newNode->left = newNode->right = NULL; // Call other Insert() to do the actual insertion return(Insert(newNode)); } //-------------------------------------------- // Function: Delete() // Purpose: Delete a node from the tree. // Preconditions: Tree contains the node to delete // Returns: int (TRUE if successful, FALSE otherwise) //-------------------------------------------- int B_Tree::Delete(int Key) { TreeNode *back; TreeNode *temp; TreeNode *delParent; // Parent of node to delete TreeNode *delNode; // Node to delete temp = root; back = NULL; // Find the node to delete while((temp != NULL) && (Key != temp->Key)) { back = temp; if(Key < temp->Key) temp = temp->left; else temp = temp->right; }

if(temp == NULL) // Didn’t find the one to delete {

Page 247: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

247

cout << “Key not found. Nothing deleted.\n”; return false; } else { if(temp == root) // Deleting the root { delNode = root; delParent = NULL; } else { delNode = temp; delParent = back; } } // Case 1: Deleting node with no children or one child if(delNode->right == NULL) { if(delParent == NULL) // If deleting the root { root = delNode->left; delete delNode; return true; } else { if(delParent->left == delNode) delParent->left = delNode->left; else delParent->right = delNode->left; delete delNode; return true; } } else // There is at least one child { if(delNode->left == NULL) // Only 1 child and it is on the right { if(delParent == NULL) // If deleting the root { root = delNode->right; delete delNode; return true; } else { if(delParent->left == delNode) delParent->left = delNode->right; else delParent->right = delNode->right; delete delNode; return true; } } else // Case 2: Deleting node with two children { // Find the replacement value. Locate the node // containing the largest value smaller than the // key of the node being deleted. temp = delNode->left; back = delNode; while(temp->right != NULL) { back = temp;

Page 248: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

248

temp = temp->right; } // Copy the replacement values into the node to be deleted delNode->Key = temp->Key; delNode->fValue = temp->fValue; delNode->iValue = temp->iValue; strcpy(delNode->cArray, temp->cArray); // Remove the replacement node from the tree if(back == delNode) back->left = temp->left; else back->right = temp->left; delete temp; return true; } } } //-------------------------------------------- // Function: PrintOne() // Purpose: Print data in one node of a tree. // Preconditions: None // Returns: void //-------------------------------------------- void B_Tree::PrintOne(TreeNode *T) {

cout << T->Key << “\t\t” << T->fValue << “\t\t” << T->iValue << “\t\t” << T->cArray << “\n”; } //-------------------------------------------- // Function: PrintAll() // Purpose: Print the tree using a recursive // traversal // Preconditions: None // Returns: void //-------------------------------------------- void B_Tree::PrintAll(TreeNode *T) { if(T != NULL) { PrintAll(T->left); PrintOne(T); PrintAll(T->right); } } //-------------------------------------------- // Function: PrintTree() // Purpose: Print the tree using a recursive // traversal. This gives the user access // to PrintAll() without giving access to // the root of the tree. // Preconditions: None // Returns: void //-------------------------------------------- void B_Tree::PrintTree() { PrintAll(root); }

Page 249: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

249

Main file used to test the tree //--------------------------------------------------------------- // File: TreeMain.cpp // Purpose: Main file for a demonstration of a binary tree // Programming Language: C // Author: Dr. Rick Coleman // Date: February, 2002 //--------------------------------------------------------------- #include <iostream> #include <string.h>

#include “B_Tree.h” using namespace std; int main(void) { B_Tree *theTree; TreeNode *newNode; // Do initialization stuff theTree = new B_Tree();

cout <<“Building tree...\n”; // Do simple insert of 15 nodes into tree. // Insert with keys in the order. // 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 // First 5 nodes are inserted using Insert1(). Remainder using Insert2() // Node 1 newNode = new TreeNode(); newNode->Key = 8; newNode->iValue = 2; newNode->fValue = 2.3f;

strcpy(newNode->cArray, “Node1”); newNode->left = newNode->right = NULL; theTree->Insert(newNode); // Node 2 // Note: Each time a new node is allocated we reuse the same pointer // Access to the previous node is not lost because it is not in the tree. newNode = new TreeNode(); newNode->Key = 4; newNode->iValue = 4; newNode->fValue = 3.4f; strcpy(newNode->cArray, “Node2”); newNode->left = newNode->right = NULL; theTree->Insert(newNode); // Node 3 newNode = new TreeNode(); newNode->Key = 12; newNode->iValue = 8; newNode->fValue = 4.5f; strcpy(newNode->cArray, “Node3”); newNode->left = newNode->right = NULL; theTree->Insert(newNode); // Node 4

Page 250: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

250

newNode = new TreeNode(); newNode->Key = 2; newNode->iValue = 16; newNode->fValue = 5.6f; strcpy(newNode->cArray, “Node4”); newNode->left = newNode->right = NULL; theTree->Insert(newNode); // Node 5 newNode = new TreeNode(); newNode->Key = 6; newNode->iValue = 32; newNode->fValue = 6.7f; strcpy(newNode->cArray, “Node5”); newNode->left = newNode->right = NULL; theTree->Insert(newNode); // Node 6 // Remainder of the nodes are inserted using Insert2()

theTree->Insert(10, 7.8f, 64, “Node6”); // Node 7

theTree->Insert(14, 8.9f, 128, “Node7”); // Node 8

theTree->Insert(1, 9.0f, 256, “Node8”); // Node 9

theTree->Insert(3, 0.9f, 512, “Node9”); // Node 10

theTree->Insert(5, 9.8f, 1024, “Node10”); // Node 11

theTree->Insert(7, 8.7f, 2048, “Node11”); // Node 12

theTree->Insert(9, 7.6f, 4096, “Node12”); // Node 13

theTree->Insert(11, 6.5f, 8192, “Node13”); // Node 14

theTree->Insert(13, 5.4f, 16384, “Node14”); // Node 15

theTree->Insert(15, 4.3f, 32768, “Node15”);

cout <<“All nodes inserted\n”; // Print the tree

cout <<“-----------------------------------------------------\n”; theTree->PrintTree();

cout <<“Press Enter to continue...”; cin.get();

cout <<“-----------------------------------------------------\n”; // Find some nodes and print them

cout <<“-----------------------------------------------------\n”; cout <<“Testing the search function\n”; newNode = theTree->SearchTree(13); if(newNode != NULL) { theTree->PrintOne(newNode); delete newNode; // Remember this is a duplicate node of the

Page 251: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

251

one in // in the tree and main() is responsible for deleting it. } else

cout <<“Search key not found.\n”; newNode = theTree->SearchTree(6); if(newNode != NULL) { theTree->PrintOne(newNode); delete newNode; } else

cout <<“Search key not found.\n”; newNode = theTree->SearchTree(1); if(newNode != NULL) { theTree->PrintOne(newNode); delete newNode; } else

cout <<“Search key not found.\n”; newNode = theTree->SearchTree(25); // Note: there is no Key=25 in the tree if(newNode != NULL) { theTree->PrintOne(newNode); delete newNode; } else

cout <<“Search key not found.\n”; // Delete some nodes

cout <<“-----------------------------------------------------\n”; cout <<“Testing delete function\n”; cout <<“-----------------------------------------------------\n”; cout <<“Testing deleting a leaf...\n”; theTree->Delete(7); // Delete a known leaf theTree->PrintTree();

cout <<“Press Enter to continue...”; cin.get();

cout <<“-----------------------------------------------------\n”;

cout <<“-----------------------------------------------------\n”; cout <<“Testing deleting a node with 2 children...\n”; theTree->Delete(12); // Delete a node known to have 2 children theTree->PrintTree();

cout <<“Press Enter to continue...”; cin.get();

cout <<“-----------------------------------------------------\n”;

cout <<“-----------------------------------------------------\n”; cout <<“Testing deleting a node with 1 child...\n”; theTree->Delete(6); // Delete a node known to have only 1 child theTree->PrintTree();

cout <<“Press Enter to continue...”; cin.get();

cout <<“--------------”“---------------------------------------\n”;

Page 252: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

252

cout <<“-----------------------------------------------------\n”; cout <<“Testing trying to delete a node that is not in the tree...\n”; theTree->Delete(7); // Delete a node that is not there theTree->PrintTree();

cout <<“Press Enter to continue...”; cin.get();

cout <<“-----------------------------------------------------\n”;

cout <<“-----------------------------------------------------\n”; cout <<“Testing deleting the root...\n”; theTree->Delete(8); // Delete the root theTree->PrintTree();

cout <<“Done.\nPress Enter to continue...”; cin.get();

cout <<“-----------------------------------------------------\n”; return 0; }

Factorial Sum - Count # of trailing zero’s

Here’s a challenge that’s a bit more mathematical in nature. Write a program that determines the number of trailing zeros at the end of X! (X factorial), where X is an arbitrary number. For instance, 5! is 120, so it has one trailing zero. (How can you handle extreme values, such as 100!?) The input format should be that the program asks the user to enter a number, minus the !.

The trick here is to realize that the limiting case is the number of times five will be a factor of X!, as 5*2 = 10, and any time the number is multiplied by 10, there will be an additional trailing zero. Due to the abundance of even numbers, there are plenty of spare twos that are factors of any number. The trick is that the number of trailing zeros in X! is the number of times five divides into the number, plus the number of times 25 divides into the number, plus the number of times 125 divides into the number, and so forth. (25 is 5*5, so when five is divided into the number, that still leaves a single 5 remaining as a factor.)

Here is one way to code it:

code #include <iostream> using namespace std; int main() { int factorialnumber = 0;

cout<<“Please enter a number: ”; cin>>factorialnumber; int zero_count = 0; for(int five_factor=5; five_factor<=factorialnumber; five_factor*=5) { zero_count += factorialnumber/five_factor; }

cout<<“Trailing zeros of”<<factorialnumber; cout<<“! is”<<zero_count<<endl; }

Page 253: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

253

Integer to English String Practice Problem Solution #include <string> #include <iostream> using namespace std;

string num_to_text[] = { “”, “one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”, “ten”, “eleven”, “twelve”, “thirteen”, “fourteen”, “fifteen”, “sixteen”, “seventeen”, “eighteen”, “nineteen” };

string tens_to_text[] = { “”, “”, “twenty”, “thirty”, “forty”, “fifty”, “sixty”, “seventy”, “eighty”, “ninety” };

string power_to_text[] = { “”, “thousand”, “million”, “billion” }; string padIfNeeded (string ans) {

if ( ans == “” ) {

return “”; }

return “” + ans; } string translateHundred (int hundred_chunk) { // handle special cases in the teens if ( hundred_chunk < 20 ) { return num_to_text[ hundred_chunk ]; } int tens = hundred_chunk / 10; int ones = hundred_chunk % 10; return tens_to_text[ tens ] + padIfNeeded( num_to_text[ ones ] ); } string translateThousand (int thousand_chunk) { if ( thousand_chunk < 100 ) { return translateHundred( thousand_chunk ); } else { int hundreds = thousand_chunk / 100; int hundred_chunk = thousand_chunk % 100;

return num_to_text[ hundreds ] + “ hundred” + padIfNeeded( translateHundred( hundred_chunk ) ); } } int main() { int n; cin >> n; string number; bool is_negative = false; if ( n < 0 ) {

Page 254: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

254

is_negative = true; n *= -1; } int chunk_count = 0; while ( n > 0 ) { if ( n % 1000 != 0 ) { number = translateThousand( n % 1000 ) + padIfNeeded( power_to_text[ chunk_count ] + padIfNeeded( number ) ); } n /= 1000; chunk_count++; }

if ( number == “ ” ) {

number = “zero”; } if ( is_negative ) {

number = “negative” + number; } cout << number << endl; }

Decimal-to-Binary Conversion Challenge Solution The logic behind the program is to find the largest power of two that fits in the decimal number; this is the first one output in the decimal number. The remainder is returned down the recursive chain, and if the current power of two at each function call fits within the remainder, then the function outputs a 1 and returns the remainder minus the amount accounted for by that place in the binary number. Otherwise a 0 is output as a placeholder and the remainder is returned to allow it to be checked against the next smallest power of two.

#include <iostream> #include <math.h> #include <ctype.h> using namespace std; int dectobin(int dec, int power_of_two) { if(dec == 0) {

cout<<“0”; } else if(dec/(int)pow(2, power_of_two)) { int remainder = dectobin(dec, power_of_two+1); if(remainder/(int)pow(2, power_of_two)) {

cout<<“1”; return remainder - (int)pow(2, power_of_two); } else {

cout<<“0”; return remainder; } } else { return dec; }

Page 255: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

255

} int main(int argc, char *argv[]) { if(argc != 2) {

cout<<“Input is of format ‘dectobin num’“; return 1; } dectobin(atoi(argv[1]), 0); }

Linked List Reverse Printing Challenge Using whatever programming techniques you know, write the cleanest possible function you can think of to print a singly linked list in reverse. The format for the node should be a struct containing an integer value, val, and a next pointer to the following node.

This code is in C; the only major difference between it and C++ are in the way that structs are declared; in C++, “node* next” is sufficient. It would, of course, be possible to replace the printf with cout if so desired.

This solution uses recursion to reverse the linked list by, in effect, placing every element on the list on the call stack. Since the first element put on a stack is the last one removed, by putting the list on the stack in order, we can remove the elements in exactly the reverse order. Other solutions that do not use recursion would need to explicitly handle the stack, perhaps by constructing a linked list in reverse order.

#include <stdio.h> struct node { int val; struct node* next; }; void print_reverse( struct node* list ) { if ( list != 0 ) { print_reverse( list->next );

printf( “%d\n”, list->val ); } }

String Permutation Challenge

Here is another mathematical problem, where the trick is as much to discover the algorithm as it is to write the code: write a program to display all possible permutations of a given input string--if the string contains duplicate characters, you may have multiple repeated results. Input should be of the form

permute string

and output should be a word per line.

Here is a sample for the input cat

cat

cta

act

atc

tac

Page 256: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

256

tca

#include <iostream> #include <string> using namespace std; string swtch(string topermute, int x, int y) { string newstring = topermute; newstring[x] = newstring[y]; newstring[y] = topermute[x]; //avoids temp variable return newstring; } void permute(string topermute, int place) { if(place == topermute.length() - 1) { cout<<topermute<<endl; } for(int nextchar = place; nextchar < topermute.length(); nextchar++) { permute(swtch(topermute, place, nextchar), place+1); } } int main(int argc, char* argv[]) { if(argc!=2) {

cout<<“Proper input is ‘permute string’“; return 1; } permute(argv[1], 0); }

File Size Challenge In this challenge, given the name of a file, print out the size of the file, in bytes. If no file is given, provide a help string to the user that indicates how to use the program. You might need help with taking parameters via the command line or file I/O in C++ (if you want to solve this problem in C, you might be interested in this article on C file I/O).

/* * This program was created by Denis Meyer (http://www.calltopower.de/blog/) */ #include <iostream> #include <fstream> using namespace std; int main (int argc, char* const argv[]) { if ( argc < 1 ) {

cout << endl << “Usage programname filename” << endl

Page 257: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

257

<< endl; return 1; } else if ( argc != 2 ) {

cout << endl << “Usage:” << argv[0] << “ filename” << endl << endl; return 1; } ifstream file(argv[1]); if(!file.is_open()) {

cout << endl << “Couldn’t open File” << argv[1] << endl << endl; return 1; } long begin, end; begin = file.tellg(); file.seekg (0, ios::end); end = file.tellg(); file.close();

cout << endl << “The Size of the File” << argv[1] << “is:” << (end-begin) << “Byte.” << endl << endl; return 0; }

Line Count Challenge Here’s a simple help free challenge to get you started: write a program that takes a file as an argument and counts the total number of lines. Lines are defined as ending with a newline character. Program usage should be

count filename.txt

and the output should be the line count.

#include <fstream> #include <iostream> using namespace std; int main(int argc, char* argv[]) { if(argc!=2) {

cout<<“Input should be of the form ‘count filename.txt’“; return 1; } else { ifstream input_file(argv[1]); if(!input_file) {

cout<<“File”<<argv[1]<<“does not exist”; return 0; }

Page 258: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

258

char c; int count = 0; while(input_file.get(c)) {

if(c == ‘\n’) { count++; } }

cout<<“Total lines in file: ”<<count; } return 0; }

Page 259: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

259

List implemented as Array C++ array doesn’t keep track of its length, but in these examples “array” class/template keeps track of its length

List implements the list interface using an array

declare

size

find

assign one array to another

Page 260: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

260

Stack implemented as Array Stack implements the list interface using an array

declare

Access and Modify

Add

Page 261: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

261

Remove

Page 262: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

262

Stack implemented as Linked List The implementation of a linked list is pretty simple in Java. Each node has a value and a link to next node.

class Node {

int val;

Node next;

Node(int x) {

val = x;

next = null;

}

}

Stack: using linked list. class Stack{

Node top;

public Node peek(){

if(top != null){

return top;

}

return null;

}

public Node pop(){

if(top == null){

return null;

}else{

Node temp = new Node(top.val);

top = top.next;

return temp;

}

}

public void push(Node n){

Page 263: C++ Design Essentials - Gregg Roeten · write to text file ... Factorial Sum - ount # of trailing zero’s ... Queue: java program to implement queue using linked list.

263

if(n != null){

n.next = top;

top = n;

}

}

}

Queue: java program to implement queue using linked list. class Queue{

Node first, last;

public void enqueue(Node n){

if(first == null){

first = n;

last = first;

}else{

last.next = n;

last = n;

}

}

public Node dequeue(){

if(first == null){

return null;

}else{

Node temp = new Node(first.val);

first = first.next;

return temp;

}

}

}


Recommended