Upload
karoli-otieno
View
131
Download
0
Embed Size (px)
Citation preview
1
Coding Standards.
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Coding Standards
Compile cleanly (no warnings)Use multiple compilers. gcc/icc suites are installed.
Makefiles are required for each project.
Coding Standards
Use of svn is mandatory. (version control)
“The palest of ink is better than the best memory”Don’t break the build. The code in the version control system (svn) should always compile.
Lot of svn tutorials on the web.
http://artis.imag.fr/~Xavier.Decoret/resources/svn/index.htmlhttp://centerstageproject.com/wiki/index.php/SVN_Tutorial
Code Review
Re-Read code. More eyes will help make better quality. Read code from good programmers. You’ll learn and benefit.It’s best to do code reviews in writing, a simple e-mail can suffice.
Correctness
Correct is better than fast.Simple is better than complex.Prefer clarity over cuteness.Write code for people first, then machines.
Optimization: Making it fast.
“Premature optimization is the root of all evil”. Don’t optimize prematurely.
Remember, “It is far easier to make a correct program fast than to make a fast program correct”.
COP 3330 Object Oriented Programming in C++ Lecture Slides 1/134 (c) pk
2
Global variables.
Minimize global and shared data.Example. You are not allowed to use “static” keyword in your code (till asked).Information Hiding: Don’t expose internal information from an entity that provides an abstraction.
Coding Style
Prefer compile and link time errors to run time errors.Use “const” proactively.Avoid macros.Avoid Magic numbers.Declare variables as locally as possible.Always initialize variables.
Coding Style
Avoid long functions (Max number of lines in a function = 25). Each line to be less than 80 characters. Make header files self-sufficient. Always write “#include” guards.
In the end…
Your software should be:ExpandableMaintainableUnderstandableStableAnd preferably built/tested/reviewed by more than one person…
COP 3330 Object Oriented Programming in C++ Lecture Slides 2/134 (c) pk
1
Doxygen Tutorial
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Documentation Generators
A documentation generator is a programming tool that generates documentation intended for programmers (API documentation) or end users (End-user Guide), or both, from a set of specially commentedsource codes.
Commenting programs
Doxygen is a documentation generator for C++, C, Java, Objective-C, Python, and to some extent PHP, C# and D. Its highly portable. (Windows/unix/linux/mac)KDevelop has builtin support for Doxygen.
Why?
Doxygen is very useful for maintaining and understanding your own larger projects as well as useful documentation for others who use your code.
How?
For each project that uses Doxygen, you must create a configuration file. “doxygen –g” creates a example configuration file called “Doxyfile”“doxygen [configfile]” will create the documentation for your code as per your configuration specs.
Configuration File
Well documented, you just need to fill in the blanks.Main things to set
PROJECT_NAME = MyProject
OUTPUT_DIRECTORY = ./doc
INPUT = ./src ./include
FILE_PATTERNS = *.cpp *.hpp
GENERATE_HTML = YES
EXTRACT_ALL = YES
COP 3330 Object Oriented Programming in C++ Lecture Slides 3/134 (c) pk
2
Documenting the source.
Beginning of file:/*! \file dpoint.hpp
\brief d-dimensional point class
A d-dimensional point class which is written carefully using templates. It allows for basic operations on points in any dimension. Orientation tests for 2 and 3 dimensional points are supported using <a href="http://www.cs.berkeley.edu/~jrs/">Jonathan's</a>code. This class forms the building block of other classes like dplane, dsphere etc.
\author <a href="www.compgeom.com/~piyush">Piyush Kumar</a>\bug No known bugs.
*/
HTML allowed
Documenting the source.
Beginning of function./*! \brief Prints character ch at the current location* of the cursor.** If the character is a newline ('\n'), the cursor should* be moved to the next line (scrolling if necessary). If* the character is a carriage return ('\r'), the cursor* should be immediately reset to the beginning of the current* line, causing any future output to overwrite any existing* output on the line. If backsapce ('\b') is encountered,* the previous character should be erased (write a space* over it and move the cursor back one column). It is up* to you how you want to handle a backspace occurring at the* beginning of a line.** \param ch the character to print* \return The input character*/int putbyte( char ch );
Creating the frontpageExample that creates first page of documentation: (You can add it to the main.cpp or main source code file)
/**@mainpage COP 3330 Project 1
@author Me and Myself
Here you should tell us about how your project works. How to run,any special things you have, etc. Also, explain any non-trivialdesign decisions you make. If you are working with a partner, clearly State what is each person’s contribution. You shouldalso comment on the stability of your code. Any big bugs should be listedhere. Basically, anything that you think we need to know in general aboutyour project should go here.
Any additional comments you want to make can go here. Did you like theproject? Was it too hard, too easy? My TA smells bad. Well, you getthe idea.
This initial documentation here should be removed.Or else you loose points.
*/
Documentation Rules.
Each file/function should have a header block.Use descriptive and meaningful names for variables, constants, and functions. Don't just re-express the algorithm in English; tell us why you're doing something.
Right: For each name in the array, extract the lastname. Wrong: Set i to 0. Loop from 0 to 10. Call strchr() on a[i],
looking for the first ' ' character. Return the pointer the character immediately following the ' '.
Documentation Rules
For each project, create a directory structure like this:
prj_?\DoxyfileMakefileREADME bin\data\doc\include\src\
Created using doxygen –gModify it after creation.
Sample project: http://www.compgeom.com/~piyush/teach/cop3330/homeworks/hw1/prj_1.tar.gz
COP 3330 Object Oriented Programming in C++ Lecture Slides 4/134 (c) pk
1
SVN Tutorial
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Setting up svn
Once you receive teamXY.cerSave it in ~/svncert directoryRun /tmp/bin/svncertinstall[Read the emailed instructions]
Run
svn ls https://svn.cs.fsu.edu/repos/team1lists all files in your repository. (empty)
svn mkdir/rm
$ svn mkdir file://svn.cs.fsu.edu/repos/team1/prj_1 -m "Create project directory"
Committed revision 1. $ svn ls file://svn.cs.fsu.edu/repos/team1prj_1$ svn rm file://svn.cs.fsu.edu/repos/team1/prj_1 -m “Delete
project directory“Remark: The -m flag is used to give a log message for the
action. Log messages are enforced by svn.
svn importing [email protected]:~/cop3330/prj_1>ls -latotal 132drwx------ 8 piyush CS-Faculty 4096 Aug 30 22:08 .drwx------ 4 piyush CS-Faculty 4096 Aug 30 22:08 ..drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 bindrwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 datadrwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 doc-rw------- 1 piyush CS-Faculty 47593 Aug 30 22:08 Doxyfiledrwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 include-rw------- 1 piyush CS-Faculty 96 Aug 30 22:08 Makefile-rw------- 1 piyush CS-Faculty 39 Aug 30 22:08 READMEdrwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 src
[email protected]:~/cop3330>svn import /home/faculty/piyush/cop3330/prj_1/ https://svn.cs.fsu.edu/repos/team1/prj_1 -m 'Initial import'
svn importing [email protected]:~/cop3330>svn import /home/faculty/piyush/cop3330/prj_1/ https://svn.cs.fsu.edu/repos/team1/prj_1 -m 'Initial import'
Adding /home/faculty/piyush/cop3330/prj_1/includeAdding /home/faculty/piyush/cop3330/prj_1/include/example.hppAdding /home/faculty/piyush/cop3330/prj_1/DoxyfileAdding /home/faculty/piyush/cop3330/prj_1/docAdding /home/faculty/piyush/cop3330/prj_1/srcAdding /home/faculty/piyush/cop3330/prj_1/src/main.cppAdding /home/faculty/piyush/cop3330/prj_1/src/MakefileAdding /home/faculty/piyush/cop3330/prj_1/binAdding /home/faculty/piyush/cop3330/prj_1/dataAdding /home/faculty/piyush/cop3330/prj_1/READMEAdding /home/faculty/piyush/cop3330/prj_1/Makefile
Committed revision [email protected]:~/cop3330/prj_1>
Cleaning and checking [email protected]:~/cop3330/prj_1>cd [email protected]:~/cop3330>rm -rf prj_1/[email protected]:~/cop3330>svn co https://svn.cs.fsu.edu/repos/team1/prj_1/A prj_1/DoxyfileA prj_1/includeA prj_1/include/example.hppA prj_1/docA prj_1/srcA prj_1/src/main.cppA prj_1/src/MakefileA prj_1/binA prj_1/dataA prj_1/MakefileA prj_1/READMEChecked out revision [email protected]:~/cop3330>cd [email protected]:~/cop3330/prj_1>
COP 3330 Object Oriented Programming in C++ Lecture Slides 5/134 (c) pk
2
The extra [email protected]:~/cop3330/prj_1>ls -latotal 132drwx------ 8 piyush CS-Faculty 4096 Aug 30 23:02 .drwx------ 4 piyush CS-Faculty 4096 Aug 30 23:02 ..drwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 bindrwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 datadrwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 doc-rw------- 1 piyush CS-Faculty 47593 Aug 30 23:02 Doxyfiledrwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 include-rw------- 1 piyush CS-Faculty 96 Aug 30 23:02 Makefile-rw------- 1 piyush CS-Faculty 39 Aug 30 23:02 READMEdrwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 srcdrwx------ 7 piyush CS-Faculty 4096 Aug 30 23:02 [email protected]:~/cop3330/prj_1>
Working with the project
$ svn add src/class.h src/class.cppA src/class.hA src/class.cpp$ svn commit –m “Added two files”
Working with the project
Checkout a fresh copy of the project every time you start working.Edit/change it.Use svn add/rm commands if you add/delete files to the projectUse svn commit command to save your changes (use this often with a meaningful –m comment)
Working with the project
Do not add .o or executable files to the svn server. Only source code.Resources:http://artis.imag.fr/~Xavier.Decoret/resources/svn/index.htmlhttp://svnbook.red-bean.com/nightly/en/svn-book.html
Project Submission
The submission script automatically checks out projects from your directory at the deadline time.Always keep your svn directory compilable. Do not check in anything that does not compiles.
COP 3330 Object Oriented Programming in C++ Lecture Slides 6/134 (c) pk
1
Make Tutorial
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Compiling programs
Single source file code:g++ -g –Wall main.cpp –lm –o main
Multiple sources [a,b]g++ -g –c –Wall a.cppg++ -g –c -Wall b.cppg++ -g –o main a.o b.o -lm
Compiler flags
-cSeparate compilation flag. Will produce a ``.o'' file only, without linking. -g
The application will have full debug capabilities, but almost no optimization will be performed on the application, leading to lower performance.-Wall
Enable all warnings.-o filename
Write output to file.For more options: “man g++”
Compilation
Multi stage processg++ -g main.cpp –lm –o main• g++ -g -c main.cpp –o main.o• g++ -g main.o main
Compiling and Linking• Compilation : Produces object code
(main.o)• Linking : Produces executable by linking a
collection of object files and libraries.
A Typical Software Project
Has 10s to 100s of source filesMultiple directoriesMultiple authorsFlags : Differ with compilation
Debugging flags (-g)Optimization flags (-O6 –malign-double)Release Vs Test builds.
Make: A tool to automate the build process. Other cool build tools: CMake, automake/autoconf, scons.
Make
Make is not tied to any particular language. Make figures out automatically which files it needs to update, based on which source files have changed. Make enables the end user to build and install your package without knowing the details of how that is done.
COP 3330 Object Oriented Programming in C++ Lecture Slides 7/134 (c) pk
2
Make and Makefiles
“make” command reads “makefile”in the current directory for instructions for the build process.If you want to give it a specific file for
input, say Makefile-1 usemake –f Makefile-1
An example
Main.cpp Uses functions from other source files and is the main program.Hello.cpp Function definition.Sumof.cpp Function definition.Functions.hpp Function declarations.
Download code from: http://www.compgeom.com/~piyush/teach/3330/examples/makex.tar.gzUse “tar zxf makex.tar.gz” to untar files.
An Example: Makefile-0
Running Makemake -f Makefile-0
g++ main.cpp hello.cppsumof.cpp -o hellomake<reads default: Makefile>
An Example: Makefile-0
The basic makefile is composed of “rules”:
target: prerequisites <tab> system command
Makefile-0
all: <tab> g++ main.cpp hello.cpp sunof.cpp -o hello
Default target for makefiles“make –f Makefile-0” and “make –f Makefile-0 all” are equivalent.
Other targetsOr source files
Targets, Prereqs and commands
Target: is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out, such as `clean' A prerequisite is a file that is used as input to create the target. A target often depends on several files. A command is an action that make carries out.
Put a tab before the command
Another Example: Makefile-1
Makefile-1
all: hello
hello: main.o sumof.o hello.og++ main.o sumof.o hello.o -o hello
main.o: main.cppg++ -c main.cpp
sumof.o: sumof.cppg++ -c sumof.cpp
hello.o: hello.cppg++ -c hello.cpp
clean:rm -rf *o hello *.exe
Dependencies
“make –f Makefile-1 clean” cleans up your directory except source code.
Prerequisites /Dependencies.
Command
Wildcards.
COP 3330 Object Oriented Programming in C++ Lecture Slides 8/134 (c) pk
3
Make
Only makes out of date prerequisites.hello: main.o sumof.o hello.o
g++ main.o sumof.o hello.o -o hello
How to decide whether “hello” is out of date?
It is out of date if it does not exist, or
if either main.o , sumof.o or hello.o are more recent than it.
If “hello” is out of date, make executes the command ‘g++ main.o …’
Another Example: Makefile-2
Makefile-2
# The variable CC will be the compiler to use.CC=g++
# CFLAGS will be the options I'll pass to the compiler.CFLAGS=-c -Wall -g
all: hello
hello: main.o sumof.o hello.o$(CC) main.o sumof.o hello.o -o hello
main.o: main.cpp$(CC) $(CFLAGS) main.cpp
sumof.o: sumof.cpp$(CC) $(CFLAGS) sumof.cpp
hello.o: hello.cpp$(CC) $(CFLAGS) hello.cpp
clean:rm -rf *o hello *.exe
Comments in makefile.
Variables
UsingVariables
Makefile targets
Expected targets in makefilesmake all
• Compile everything.make install
• Install your software.make clean
• Clean intermediate files and executables.
Make: How does it work?
make reads the makefile in the current directory and begins by processing the first rule. (in our case: all)but before make can fully process this rule, it must process the rules for the files that ‘all’ depends on, which in this case are the object files. Each of these files is processed according to its own rule.
Make: How does it work?
For any rule, the recompilation must be done if the prerequisites are more recent than the target, or if the target/object file does not exist.
Make: Wrap up
make –j2Uses 2 processors for the build process.
More info:http://www.gnu.org/software/make/manual/html_node/index.htmlman makeExample : http://www.compgeom.com/~piyush/teach/3330/examples/makex.tar.gz
COP 3330 Object Oriented Programming in C++ Lecture Slides 9/134 (c) pk
1
C++ Tour
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Administrative Trivia
About me: Piyush KumarPhone: 645-2355Email: [email protected] hours: Tuesday 4:30 to 5:30.
TAs: Ryan Walega and Yuhua Zhu
More details on the course information sheet.
Your ID
You have been assigned an ID on the Blackboard. You should know your ID.
Your ID will be used to setup your Subversion (svn) repository.
http://www.compgeom.com/~piyush/teach/3330/handouts/SVN_Setup.pdf
Announcement
First Quiz : On Thursday. Will test your background knowledge.Revise your previous C/C++ material.Your first assignment will be posted on Wednesday.
Will be due on Tuesday, 9/5/06.You are required to setup your svn
repository by this Thursday. The submission will use the svn server.
Announcement
Blackboard Discussions already setup.Make sure you submit the pre-reqform today before you leave.SVN generation of certificates (demo).
C++ Tour
COP 3330 Object Oriented Programming in C++ Lecture Slides 10/134 (c) pk
2
Why learn C++?
UbiquitousObject Oriented
Easier large scale projectsResuability
High Performance
C++ Features
Supports data securityPrevents accidents with dataHelps code reuse.Lets you use operators the way you like.Allows multiple functions/operators with the same name.
When to use C++?
Large projectsSystem applicationsGraphicsData StructuresSpeed is an issue?Changes in functionality required.Need exceptions and error handling?Want to speed up your scripts?
When not to use C++?
Small system programs.Fast prototyping.Web-based applications (Perl/Python)
Important definitions
Algorithm: Ordered set of actions to accomplish a certain task.Program: Implementation of algorithms.Compiler, function, library, bug.Variables, constants.Keywords (if, while, for,…)Data Types. (long, int, …)
Compiling/Running programs
Single source file code:g++ -g –Wall simple.cpp –o simple
Compilation / Editing DemoEditors: vim / xemacsXemacs tutorial: hanson.geog.udel.edu/cmg/Handouts/xemacs_tutorial.pdfVi/vim tutorial : http://www.biochem.ucl.ac.uk/~mckenzie/vim/tutorial.html
int main() {return 0;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 11/134 (c) pk
3
simple.cpp
int main() // Function Declaration// Function body follows
{ // Block of statements begins.
return 0;
} // Block ends.
simple.cpp
On Unix: echo $?
On Windows: echo %ERRORLEVEL%
Simple.s (using g++ -O –S simple.cpp)
.file “simple.cpp".def ___main; .scl 2; .type 32; .endef.text.align 2.p2align 4,,15
.globl _main.def _main; .scl 2; .type 32; .endef
_main:pushl %ebp ; Save base pointermovl $16, %eaxmovl %esp, %ebp ; Set up stack frame for debugger subl $8, %esp ; Save space on the stackandl $-16, %esp ; Align stack pointer call __alloca ; Platform dependent callcall ___main ; Platform dependent callleave ; free space, pop ebp, esp…xorl %eax, %eax ; zero eaxret ; return control to calling procedure.
System dependent
Simple.s (using VC++ 05 compiler)//{00411360 push ebp 00411361 mov ebp,esp 00411363 sub esp,0C0h 00411369 push ebx 0041136A push esi 0041136B push edi 0041136C lea edi,[ebp-0C0h] 00411372 mov ecx,30h 00411377 mov eax,0CCCCCCCCh 0041137C rep stos dword ptr es:[edi] // return 0;0041137E xor eax,eax //}00411380 pop edi 00411381 pop esi 00411382 pop ebx 00411383 mov esp,ebp 00411385 pop ebp 00411386 ret
G++ Compilation.
preprocessing (to expand macros) Try “cpp simple.cpp > simple.i”
compilation (from source code to assembly language) Try “g++ -Wall –S simple.i”
assembly (from assembly language to machine code) Try “as simple.s -o simple.o”
linking (to create the final executable) Try “gcc simple.o”Equivalent to “ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i686/3.3.1/crtbegin.o -L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o”
$ file ./a.exe Identify type of file generated (gcc on windows)../a.exe: PE executable for MS Windows (console) Intel 80386 32-bit
Introduction to C++
COP 3330 Object Oriented Programming in C++ Lecture Slides 12/134 (c) pk
4
Organization
C++ = C + objects + …Main Theme : ObjectsClass Vs ObjectData Hiding and AbstractionEncapsulationInheritanceOperator and Function OverloadingPolymorphism.Generic Programming
C++ is a superset of C.
Features present in C are also present in C++C++ is a object oriented programming language ( C++ = c + objects + …)OOP is about objects which contain data and functions to manipulate that data.A single unit that contains data and functions that operate on the data is called an object.
Main Theme: objects
C++ enables you to focus on discrete objects that contain both data and functions to manipulate that data.Instead of data and functions as separate entities as was the case in C.Application = Collection of Objects.
Makes complex programs easy to code.
OOP
Based on concept of objects and classes.Objects: Represent entities with related state and behaviour
Instances of a classClasses: Define common characteristics of similar objects.
Objects/Classes
Objects are reusable self-contained programming modules with data and functions.Classes are blue-print for objects with common properties, attributes, operations and behaviors.
The principal building blocks of OO programs are classes and objects.
Object / Class Example
Attributes:ManufacturerModelColorEngine
Behavior:AccelerateBreakSteerTune Up
Car Class
Objects: Instantiations of classes.
COP 3330 Object Oriented Programming in C++ Lecture Slides 13/134 (c) pk
5
Another Object / Class example
class Point {
int _x, _y; // point coordinates
public: // begin interface section
void setX(const int val); void setY(const int val); int getX() { return _x; } int getY() { return _y; }
};
Point tpoint; // defines an object tpoint
Fundamental building block of OOP: A Class
A class defines a data type, much like a struct would be in C. A class is a source code for an object (hence it has both data+memberfunctions)
class
Attributes…
Methods…
Fundamental building block of OOP: A Class
You can imagine that int is a class that has member functions called operator++, etc. An object usually means an instance of a class
After the declaration int i; we say that "i is an object of type int."
Data HidingObjects contain informationOnly part of the information contained in the object might be presented to the user. Rest is concealed.
Interface
Engine
Data HidingInternal dynamics are not visible to the user.Data hiding is done by using the “private” keyword in the class definition.
Interface
Engine
Data HidingAllows data to be accessed by certain functions class Point { // private
// concealed infoint _x, _y; // point coordinates
public: // begin interface section
void setX(const int val); void setY(const int val); int getX() { return _x; } int getY() { return _y; }
};
Point tpoint; // defines an object tpoint
tpoint._x = 5; // ILLEGAL
COP 3330 Object Oriented Programming in C++ Lecture Slides 14/134 (c) pk
6
Data Abstraction
DA is a programming technique where one separates the interface from the implementationClass designer worries about the implementationProgrammers only need to know the interface.
String s; s.rfind(‘\’);
Data Encapsulation
Combine lower level elements to form a new higher level entity.Grouping of attributes and behaviors to form an object.
C++ vector type is an example of both data abstractionand Data encapsulation
OOP : Inheritance
Many classes have common attributes.These classes can be arranged in a hierarchy.Inheritance enables you to reuse code and add data and functionality without making any changes to the existing code.
For example, objects can inheritcharacteristics from other objects.
Inheritance
Children inherit traits from their parents.When a class is inherited all the functions and data member are inherited, although not all of them will be accessible by the member functions of the derived class.
Inheritance
protected/public members of the base class are accessible to the derived classprivate members are not.
class vehicle {protected:
char colorname[20];int number_of_wheels;
public:vehicle();~vehicle();void start();void stop();void run();
};
class Car: public vehicle {protected:
char type_of_fuel;public:
Car();};
Subclass or derived classSuper class or Base class
Inheritance
Derived classes are specialized form of their base class.Abstract class : A base class that is undefined and unimplemented.
COP 3330 Object Oriented Programming in C++ Lecture Slides 15/134 (c) pk
7
Multiple definitions…?
C++ allows for the same function (or overloaded operator) to have multiple defintions.
Swap(int& I, int& j);Swap(string& I, string& j);Swap(double& I, double& j);
a.k.a. Function overloading.
Operator Overloading
C++ gives you the power to define operators on user defined types.Example:
MyMatrix m = m1 + m2; // cant do this in C.Overloading is a type of polymorphism.Not all operators can be overloaded in C++.
Polymorphism
Base Class MyShape establishes the common interface to anything inherited from MyShape.All shapes can be drawn and erased.
MyShape
2DShape 3DShape
Circle Square Triangle Sphere Cube Tetrahedron
Methods:Draw()Erase()
Polymorphism
Overriding: When a child class extends the functionality of its parent class.Polymorphism allows the programmer to implement different draw/erase methods for derived classes.Sphere and Cube have the same function draw() with different functionality.
MyShape
2DShape 3DShape
Circle Square Triangle Sphere Cube Tetrahedron
Methods:Draw()Erase()
Polymorphism
No matter what shape the object is, one can use the “draw” method to draw it correctly.
MyShape
2DShape 3DShape
Circle Square Triangle Sphere Cube Tetrahedron
Methods:Draw()Erase()
Polymorphism
Using operators and functions in different ways depending on what they are operating on is called polymorphism.
StaticDynamic
The concept builds upon encapsulation and inheritance.
COP 3330 Object Oriented Programming in C++ Lecture Slides 16/134 (c) pk
8
Generic Programming
Type independent codeWrite code for one generic type and use it for multiple types.
Without Generic Programming: void swap(int & x, int & y) { int tmp = x; x = y; y = tmp; } void swap(long & x, long & y){ long tmp = x; x = y; y = tmp; }…
With Generic Programmingtemplate <typename T>
void swap(T & x, T & y) { T tmp = x; x = y; y = tmp; }
COP 3330 Object Oriented Programming in C++ Lecture Slides 17/134 (c) pk
1
Basic and Library Types
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Basic C++ Types
integer data-types : char, short, int, long, unsigned char, unsigned short,…
floating point data-types :float, double, long double
logical data-type : boolbool constants : true, false
character data-type : char and wchar_tChar constants in single quotes : ’a’
text data-type :stringstring constants in double quotes : ”Hello world”
Basic C++ Types
voidReturn type for a function with no return valuevoid pointers
unsigned and signed integersunsigned char x = -1; ?unsigned short int x = -1; ?
0 255-1
254-2Wrap around effect.Machine dependent.
Recommended assignments: 2.4/2.7/2.8/2.9
Basic Arithmetic types
10193.4x1049323.4x10-4932long double
8151.7x103081.7x10-308double
473.4x10383.4x10-38float
4-2147483647-2147483648long
4-2147483647-2147483648int
2-32767-32768short
1-127-128char
BytesDigits of Precision
HighLowType
Variable Naming
Read about hungarian naming: http://en.wikipedia.org/wiki/Hungarian_notationhttp://www.idleloop.com/hungarian/hungarian.htmlhttp://www.totse.com/en/technology/computer_technology/hungnote.htmlUse them in your next assignment onwards.
Hungarian naming
Three partsBase TypeOne or more prefixesQualifier
COP 3330 Object Oriented Programming in C++ Lecture Slides 18/134 (c) pk
2
Hungarian Base Types
Specifies the type of the variable being namedNot for predefined typesExample:
wn = Windowscr = Screenfon = Fontpa = Paragraph
Example:WN wnMain=NULL;FONT fonUserSelected = TIMES_NEW_ROMAN;
Prefixes
Go in front of the base type Somewhat standard list:
a = Arrayc = Countd = Differencee = Element of an arrayg = Global variableh = Handlei = index to arraym = Module-level variablep(np, lp) = Pointer (near or long)
Describes how the variable will be used.Examples
Array of windows: awnDialogsHandle to a window: hwnMyWindowNumber of fonts: cfon
Qualifiers
The rest of the variable name in case you were not using Hungarian naming.
More Examples
bBusy : booleancApples : count of items dwLightYears : double wordfBusy : boolean (flag) iSize : integerfpPrice: floating-pointdbPi: doublepFoo : pointerrgStudents : array, or range szLastName : zero-terminated string u32Identifier : unsigned 32-bit integerm_nWheels : member of a class, integer
Variables
What you should know?Machine level representation of built in types.Difference between : ‘a’ and “a”Type of every entity in our program should be known to the compiler.
Variables
Declarationextern int i;
Definitionint i;Is also a declaration
Type specifier
COP 3330 Object Oriented Programming in C++ Lecture Slides 19/134 (c) pk
3
Variable Initialization
Direct initialization• float funity (1.0);• std::sting all_nines(10,’9’); // #include <string>
• Happens when a variable is created and gives the variable its initial value.
Copy initialization• float funity = 1.0;• Assignment involves replacing the current
value of the variable with a new one.
Can be more efficientfor general classes.
More on this when we do “class” in detail.
RecommendedExercises: 2.15/2.16
Coding Standards
Always initialize your variablesDefine variables where they are used.Pick names carefully.Be careful about scopes of variables
Global ScopeLocal ScopeStatement scope
Const Qualifier
for (int Index = 0; Index < 512; ++Index)const int ibufSize = 512;ibufSize = 0; // error: attempt to write to const objectconst int I , j = 0; What is wrong?Const objects are local to a file by default.Prefer const to #define
Using const instead of #define allows much better type checking and reduces name space pollution.
Const qualifier
Const member functionsSpecify which member functions can be invoked on const objects.Class Rational { …public:
…const int numerator(void);…const Rational operator+(const Rational& rhs) const;
}
const Rational operator+(const Rational& lhs,const Rational& rhs);
Const qualifier
Const member functionsSpecify which member functions can be invoked on const objects.
Class Rational { …public:
…const int numerator(void);…const Rational operator+(const Rational& rhs) const;
}
Rational a,b,c; a = b+c;But does not allow (a+b) = c;
Const qualifier
Const member functionsSpecify which member functions can be invoked on const objects.const Rational operator+(const Rational& lhs,
const Rational& rhs);
When operator+ is a member function, a = b+c is allowed, but what if you want to doa = c + 2;a = 2 + c;Mixed mode operations are the reason why operatorsare usually defined outside the class.
COP 3330 Object Oriented Programming in C++ Lecture Slides 20/134 (c) pk
4
References
What is a reference?An alternate name for an object.Frequently used for pass by reference.
void swap(int& i, int& j){
int tmp = i;i = j;j = tmp;
}
int main(){
int x, y;...swap(x,y);...
}
Here i and j are aliases for main's x and y respectively. In other words, i is x — not a pointer to x, nor a copy of x, but x itself. Anything you do to i gets done to x, and vice versa.
References
A reference is an alias.Int ival = 1024; int &refVal = ival;refVal += 2; // increases ival.
Errors:int &refVal2 = 10; // a reference must be initialized.Int &refVal3;
Const references
A reference that refers to a const object.
const int ival = 1024;const int& refval = ival;const double& pi = 3.14; // only legal for const references
Errors:Int &ref2 = ival; // Non-const reference to a const object.
Const references#include <iostream>using namespace std;
int main(void){int dval = 100;const int& ref = dval;ref++;return 0;
}
What is wrong?
Typedef namesTypedef lets us define a synonym for a type.
typedef double wages;typedef int exam_score;typedef wages salary;typedef int Pounds, Shillings, Pennies, Dollars, Cents;
Variable definitions:wages wage1,wage2;exam_score person1, person2;
-----------------------------------------------------------------------------------typedef struct { int scruples; int drams; int grains; } WEIGHT;
typedef class { public:
int scruples; int drams; int grains; } WEIGHT;
Back to the C++ Class
The C++ ClassSimilar to a structDefines what objects of a class are (what attributes describe them)Usually contains functionality in addition to attributes
The ObjectAn instance of a classA variable declared to be of a "class type“
class member: a component of a class; may be either a data item or a function
COP 3330 Object Oriented Programming in C++ Lecture Slides 21/134 (c) pk
5
Class example
Write a class to represent a two dimensional point.What data attributes do we need?What operations?
2D Point class
DataPosition
OperationsSet PositionGet PositionDistance from another point
Your first class.#ifndef POINT2D_HPP#define POINT2D_HPP
class point2D{int _x,_y;
public:void setX(const int val);void setY(const int val);int getX();int getY();double double_distance(point2D& p);
} ;
typedef Point2D Cell_tower;typedef Point2D Cell_phone;
// Implementation goes here…
#endif
Include guards
Private
Interface
Using the point2D class
Point2D p,q;p.setX(10); p.setY(10);q.setX(0); q.setY(10);
Cout << “Distance between p and q is “<< p.distance(q) << endl;
Implementing the point2D class.
#ifndef POINT2D_HPP#define POINT2D_HPP
class point2D{int _x,_y;
public:void setX(const int val) {
_x = val; }
// … Rest of the interface/implementation…} ;
typedef Point2D Cell_tower;typedef Point2D Cell_phone;
// Implementation goes here…
#endif
Implementing the point2D class.
#ifndef POINT2D_HPP#define POINT2D_HPP
class point2D{int _x,_y;
public:void setX(const int val) ;
// … Rest of the interface/implementation…} ;
typedef point2D Cell_tower;typedef point2D Cell_phone;
// Implementation goes here…void point2D::setX(const int val){
_x = val;}
#endif
Can be also implementedin point2D.cpp
COP 3330 Object Oriented Programming in C++ Lecture Slides 22/134 (c) pk
6
Headers
Always use #include guardsDo not define variables or functions in headers except
Class definitionsConst objectsInline functions
Difference between#include <myfile.h> #include “myfile.h”
Header files
point2D.hppmain.cpp point2D.cpp
main.o
prj_2
point2D.o
Compiler Compiler
Linker
#include “point2D.hpp”
implementation file
Header file
main program
h
often several program files use the same header file containing typedef statements, constants, or class type declarations--but, it is a compile-time error to define the same identifier twice
this preprocessor directive syntax is used to avoid the compilation error that would otherwise occur from multiple uses of #include for the same header file
#ifndef Preprocessor_Identifier#define Preprocessor_Identifier
.
.
.#endif
Avoiding Multiple Inclusion of Header Files Using the MyTimer class
#include “timer.hpp”
MyTimer time_elapsed;// your code goes here…
cout << time_elapsed;
A Problem with #define.
#define max(a,b) ((a) > (b) ? (a) : (b))int a = 10, b = 20;max(a,b)max(++a,b)max(++a,b+10)
COP 3330 Object Oriented Programming in C++ Lecture Slides 23/134 (c) pk
1
C++ IO
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
C++ IO
All I/O is in essence, done one character at a time
Concept: I/O operations act on streams (sequences) of ASCII characters
C++ IO
cout standard output streamsequence of characters printedto the monitor
cin standard input streamsequence of characters inputfrom the keyboard
both cout and cin are data objectsand are defined as classes
<iostream> vs <cstdio>
More type-safe: With <iostream>, the type of object being I/O'd is known statically by the compiler. In contrast, <cstdio> uses "%" fields to figure out the types dynamically. Less error prone: With <iostream>, there are no redundant "%" tokens that have to be consistent with the actual objects being I/O'd. Removing redundancy removes a class of errors. Extensible: The C++ <iostream> mechanism allows new user-defined types to be I/O'd without breaking existing code. Imagine the chaos if everyone was simultaneously adding new incompatible "%" fields to printf() and scanf()?! Inheritable: User defined streams possible.
#include <iostream>
cin
( type istream )class
cout
( type ostream )class
Keyboard Screenexecutingprogram
input data output data
Interactive I/ONamespaces: They provide a way to avoid name collision.Be careful about using this.
Example
#include <iostream>
using namespace std;
int main(void){
cout << “Hello World” ;cout << endl;return 0;
}
Standard IO libraryfor C++. Defines two fundamental types,istream and ostream.
Stream: A flow of characters (1 or 2 bytes long). Can flow in and out of Files, strings, etc.
COP 3330 Object Oriented Programming in C++ Lecture Slides 24/134 (c) pk
2
Example
#include <iostream>
using namespace std;
int main(void){
cout << “Hello World” ;cout << endl;return 0;
}
Ostream object named cout.
Equivalent to:operator<< (cout, “Hello World”);
Its calling a friend function of ostream with input data.
Uses function declaration (approx):ostream& operator<<( ostream&, const char * )
Example
#include <iostream>
using namespace std;
int main(void){
cout << endl;return 0;
}
invokes a manipulator function called endl. endl looks something like this:
ostream& endl( ostream& os) {
os << '\n'; os.flush(); return os;
}
Equivalent Compiler statement:std::cout.operator<<(
std::endl(std::cout));
Scope Operator for namespaces.
\n new line\t tab\b backspace\r carriage return\' single quote\" double quote\\ backslash
Special Output Characters Stream IO headers
iostream -- contains basic information required for all stream I/O operationsiomanip – used for performing formatted I/O with stream manipulatorsfstream – used for performing file I/O operationsstrstream -- used for performing in-memory I/O operations (i.e., into or from strings in memory)
A Stream
A flow of characters.Buffers: IO to streams goes thru a buffer. C++ allows you change the default behavior of associated buffers.State: Each stream is associated with a state indicating various things like if an error has occurred or not…
C++ IO Class hierarchyios
istream ostream
istringstream ostringstreamifstream ofstream
stringbuf
streambuf
filebuf
COP 3330 Object Oriented Programming in C++ Lecture Slides 25/134 (c) pk
3
C++ IO Class hierarchyios
istream ostream
istringstream ostringstreamifstream ofstream
stringbuf
streambuf
filebuf
coutcin
C++ IO Hierarchy
The ios hierarchy defines the interface of the IO system. The streambuf hierarchy defines the implementation of the IO system, mostly provides the facilities of buffering and byte-level I/O
Other Predefined Streams
cerr - the standard destination for error messages (often the terminal window). Output through this stream is unit-buffered, which means that characters are flushed after each block of characters is sent. clog - like cerr, but its output is buffered.
Formatting with predefined streams.
Remember: Due to inheritance, anything you learn about formatting IO with predefined streams (cin, cout, clog, cerr) also applies to file IO and string IO.Anything available or defined in the ios class is available everywhere in the IO subsystem.
Stream IO
<< (left-shift operator)Overloaded as stream insertion operator
>> (right-shift operator)Overloaded as stream extraction operator
Both operators used with cin, cout, cerr, clog, and with user-defined stream objects
Inside ios
Example
cin >> Variable;cout << Variable;clog << Variable;
Bufferedcerr << Variable;
Unbuffered, prints Variable immediately.
Note: Variable types are available to the compiler.
COP 3330 Object Oriented Programming in C++ Lecture Slides 26/134 (c) pk
4
<< operator
<< is overloaded to work on built-in types of C++. Can also be used to output user-defined types.Other interesting examples:
cout << ‘\n’; // newline.cout << “1+2=” << (1+2) << endl;cout << endl; // newline.cout << flush; // flush the buffer.
<< operator
Associates from left to right, and returns a reference to its left-operand object (i.e. cout). This enables cascading.Outputs “char *” type as a string.If you want to print the address, typecast it to (void *).Example:
char name[] = “cop3330”;cout << name << static_cast<void *>( name ) << endl;static_cast<void *>( name ) equivalent to ((void *) name) in C except that it happens at compile time.
Stream insertion: One char.
put member functionOutputs one character to specified streamcout.put(‘C');Returns a reference to the object that called it, so may be cascadedcout.put( ‘C' ).put( '\n' );May be called with an ASCII-valued expressioncout.put( 65 );
• Outputs A
Input Stream
>> (stream-extraction) Used to perform stream inputNormally ignores whitespaces (spaces, tabs, newlines)Returns zero (false) when EOF is encountered, otherwise returns reference to the object from which it was invoked (i.e. cin)
• This enables cascaded inputcin >> x >> y;
>> controls the state bits of the streamfailbit set if wrong type of data inputbadbit set if the operation fails
Input Stream : Looping
while (cin >> fname)
“>>” returns 0 (false) when EOFencountered and loop terminates.
Example Program#include <iostream>
using std::cout;using std::cin;using std::endl;
int main(void) {int height = 0, maxheight = 0;
cout << "Enter the heights: (enter end of file to end): ";while(cin >> height)if( height > maxheight)maxheight = height;
cout << "Tallest person's height = "<< maxheight << endl;
return 0;}
COP 3330 Object Oriented Programming in C++ Lecture Slides 27/134 (c) pk
5
Output
$ ./a.exeEnter the heights: (enter end of file to end): 728954336866Tallest person's height = 89
istream member function: get
char ch = cin.get();Inputs a character from stream (even white spaces) and returns it.
cin.get( c );Inputs a character from stream and stores it in c
istream member function: getget (array_name, max_size) ;
char fname[256]cin.get (fname, 256);
Read in up to 255 characters and inserts a null at the end of the string “fname". If a delimiter is found, the read terminates. The array acts like a buffer. The delimiter is not stored in the array, but is left in the stream.
istream member function: getline (array_name, max_size)
char fname[256]cin.getline (fname, 256);
Same as get, except that getlinediscards the delimiter from the stream.
istream member functions:ignore()
cin.ignore ( ) ;Discards one character from the input stream.
cin.ignore (10) ;Discards 10 characters.
cin.ignore(256,’\n’);Discards 256 characters or newline, whichever comes first.
istream member functions:peek(), putback()
char ch = cin.peek ( ) ;Peeks into the stream’s next character.
cin.putback (‘A’) ;Puts ‘A’ back in the stream.
COP 3330 Object Oriented Programming in C++ Lecture Slides 28/134 (c) pk
6
FILE IO Example.Copy File “first.txt” into “second.txt”.
#include <iostream>#include <fstream>
using namespace std;
int main(void){
ifstream source("first.txt");ofstream destin("second.txt");
char ch;while (source.get(ch))
destin<<ch;return 0;
}
Slightly modified#include <iostream>#include <fstream>
using namespace std;
int main(void){
ifstream source("first.txt");ofstream destin("second.txt");
char ch;while (source.peek() != EOF){
source.get(ch);destin.put(ch);
}return 0;
}
More IO functions
read()cin.read(fname, 255);
• Reads 255 characters from the input stream. Does not append ‘\0’.
cout.write(fname,255);• Writes 255 characters.
gcount: returns the total number of characters read in the last input operation.
C++ IO Class Hierarchy Revisited
ios
istream ostream
istringstream ostringstream
ifstream ofstream
stringstream
iostream
coutcin
fstream
Another example#include <iostream>#include <sstream>#include <string>
using namespace std;
int main() {int i;string line;while(getline(cin,line)){
stringstream sfstream(line);while (sfstream >> i){
cout << i << endl;}
}return 0;
}
What if I replace thiswith istringstream?
stringstream operations
stringstream strm;stringstream strm(mystring);
Initializes strm with a copy of mystring.strm.str();
Returns the content of strm in string format.
strm.str(s);Copies the string s into strm. Returns void.
COP 3330 Object Oriented Programming in C++ Lecture Slides 29/134 (c) pk
7
Stream Manipulators
#include <iomanip> dec, hex, oct, setbase
oct, hex, decCout << hex << 15;
• Prints ‘F’
cout << setbase(16) << 15;Prints ‘F’ again.
Formatting Output - Integers
int numstdts = 35533;cout << “FSU has" << numstdts
<< "students."printsFSU has35533students.
default field width == minimum requireddefault: what happens when explicit formatting is not specified
Formatting Output - Integers p.2
we can specify the field width, or number of spaces used to print a value
cout << “FSU has" << setw(6)<< numstdts << " students."
printsFSU has 35533 students.
prints in field width 6, right-justified
function call
Formatting Output - Integers p.3
cout << “FSU has" << setw(10)<< numstdts << " students."
printsFSU has 35533 students.
prints in field width 10, right-justified
Formatting Output - Integers p.4
cout << left; // flip to left justification
cout << “FSU has " << setw(10)<< numstdts << "students."
printsFSU has 35533 students.
prints in field width 10, left-justified
COP 3330 Object Oriented Programming in C++ Lecture Slides 30/134 (c) pk
8
Using the default - Integers p.5Note on field widths: if a field width specified is too small, or is not specified, it is automatically expanded to minimum required
numstdts = 100;cout << “FSU has "
<< numstdts << " students."prints
FSU has 100 students.
and works for any value of numstdts
General Rule of Thumb
When you are printing numeric values in sentences or after a verbal label, the default field width usually works well
When you are printing numeric values lined up in columns in a table, it is usually necessary to call setw to generate well-formatted output (we will see examples of this later in the course)
Formatting Output - Realsfloat cost = 5.50;cout << "Cost is $" << cost
<< "today."printsCost is $5.5today.
defaultlarge values printed in scientific notationif number is whole, no decimal pointnumbers of digits not under your control
Formatting Output - Reals p.2Setting up real formatting
// use fixed point notationcout << fixed;
// print a decimal point (with whole numbers)cout << showpoint; ( noshowpoint )
these remain in effect until changed explicity, as does setprecision. setw only changes next value printed.
Formatting Output - Reals p.3
float cost = 5.50;cout << "Cost is $" << setw(5)
<< setprecision(2) << cost<< " today."
printsCost is $ 5.50 today.
if no field width is specified, minimum is used, just as for integers
You can just do this, once:
cout << fixed << showpoint<< setprecision(2);
and these settings will remain in effect throughout your program run
COP 3330 Object Oriented Programming in C++ Lecture Slides 31/134 (c) pk
9
Formatting Output - chardefault field width == 1note: setw does have effect on
char type data too.
char ch = 'Q';cout << '*' << ch << setw(3) << '*';
prints*Q *
Formatting Output - Stringsdefault field width == number of
characters in the string
can use setw
cout << setw(10) << "Hello";prints
Hello
Useful Output Spacerconst string BLANK = " ";
cout << setw(10) << BLANK;prints 10 blanks
consider this:const char BLANK = ' ';cout << setw(10) << BLANK;prints 10 blanks!
Unitbuf manipulator
If you want to flush every outputCout << unitbuf
<< “first”<< “second”<< nounitbuf;
Example Quiz#include <iostream> #include <iomanip>
using namespace std;
int main() { const double tenth = 0.1; const float one = 1.0; const float big = 1234567890.0; cout << "A. " << tenth << ", " << one << ", " << big << endl; cout << "B. " << fixed << tenth << ", " << one << ", " << big << endl; cout << "C. " << scientific << tenth << ", " << one << ", " << big << endl; cout << "D. " << fixed << setprecision(3) << tenth << ", " << one << ", " << big << endl; cout << "E. " << setprecision(20) << tenth << endl; return 0;
}
A. 0.1, 1, 1.23457e+009 B. 0.100000, 1.000000, 1234567936.000000 C. 1.000000e-001, 1.000000e+000, 1.234568e+009 D. 0.100, 1.000, 1234567936.000 E. 0.10000000000000000555
Manipulators: Rolling your own.
#include <iostream>#include <ostream>
using namespace std;
ostream& myendl( ostream& os) {os << "test\n";os.flush();return os;
}
int main(void) {cout << myendl;return 0;
}
•How to create our own stream manipulators?
bellret (carriage return)tabendLine
An Example.Copy not allowedon ostreams.
COP 3330 Object Oriented Programming in C++ Lecture Slides 32/134 (c) pk
10
Stream Error States
Error states
strm::eofbitif (cin.eof() == true) break; // stream end of file.
strm::failbitif ( cin.fail() == true) break; // stream format error.
strm::badbitIf (cin.bad() == true) break; // data lost!
Goodbit?cin.good() = ((!eofbit) && (!failbit) && (!badbit))All eofbit, failbit and badbit should be false.
cin.clear() // makes cin good.
Error States Example
int ival;
While ( cin >> ival, !cin.eof() ){Assert( !cin.bad() , “IO stream corrupted”);if (cin.fail()){ //bad input
cerr << “Bad data, try again.”;cin.clear(istream::failbit); // reset the streamcontinue;
}// ok to process ival now
} //end of while.
Operators for testing.
operator!• Returns true if badbit or failbit set
Useful for file processing• if ( ! readmefile ) cerr << “Error”;
Interactive Input
Write a promptmake it friendly and informative
prompt typically contains prefixcharacter to signal point at which to enter input
Read value(s)user types data at keyboard
Interactive Input: Example
int num;char response;
cout << "Enter a number -> ";cin >> num;
cout << "Enter Y or N -> ";cin >> response;
prefix
COP 3330 Object Oriented Programming in C++ Lecture Slides 33/134 (c) pk
11
Interactive Input: Contents of Output Window
Enter a number -> 17<return>
Enter Y or N -> Y<return>
the program will not process the input until the return key is struck
Another C++ Program (Hello argv[1])
#include <iostream>using namespace std;
int main(int argc, char *argv[]) {if (argc != 2) {
cout << "Usage: hi.exe <name>" << endl;exit (1);
}
cout << "Hello " << argv[1] << endl;return 0;
}
Control structures
Statements you should already know :WhileForIf
Recommended Assignments: 1.17, 1.25
COP 3330 Object Oriented Programming in C++ Lecture Slides 34/134 (c) pk
1
Introduction to the C++ Standard Library.
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
The C++ Standard Library
Provides the ability to use:String TypesData Structures (linked list, dynamic arrays, priority queues, binary trees etc)Algorithms (Sorting and Searching…)IOClasses for internationalization support.
The C++ Standard Library
Not very homogeneous:String classes are safe and convenient to use (almost self explanatory).The Standard Template Library (STL) optimizes for performance and is not required to check for errors. To use it well, you need to understand the concepts and apply them carefully.
C++ Standard Library
ContainersObjects that hold/contain other objects.Examples: vector, string
AlgorithmsWork on the containers Examples: sort, search
IteratorsProvide pointer like interface to containers.
Other components
Allocators: Provide memory management for containers. Can be customized.Adaptors: A mechanism to make one thing act like another. Example: Stack.Function objects: A function object or a functor, is a construct allowing an object to be invoked or called as if it were an ordinary function,
Containers
Of course: Contain objects/built in types.
More powerful than arrays.Grow (and shrink?) dynamicallyManage their own memoryKeep track of their sizeAllow optimal algorithmic operations like scan, sorts etc.
COP 3330 Object Oriented Programming in C++ Lecture Slides 35/134 (c) pk
2
Containers
Standard STL sequence Containers:vector, string, deque and list
Standard non-STL containers:bitset, valarray, priority_queue, queue.
Containers
Prefer sequential containers to arrays.Use vector by defaultUse list when there are a lot of insertions/deletions in the middle of the sequence.Use deque when there is a lot of insertion at the beginning or the end of the sequence.
What is a vector?
A contiguous array of elementsThe first “size” elements are constructed (initialized)The last “capacity - size” elements are uninitializedFour data members
data pointersizecapacityallocator
data size
capacity
allocator
or equivalent
datasizecapacityallocator
Sample data layout: Internals.
Vector Interfacetemplate <class T, class Allocator = allocator<T> >class vector {public:
...explicit vector(const Allocator& = Allocator());explicit vector(size_type n, const T& value = T(),
const Allocator& = Allocator());...void reserve(size_type n);...void resize(size_type sz, const T& c = T());...void push_back(const T& x);void pop_back();...iterator insert(iterator position, const T& x);void insert(iterator position, size_type n, const T& x);...iterator erase(iterator position);iterator erase(iterator first, iterator last);...void clear();
};
Vectors
template <class T, class Allocator = allocator<T> > class vector { …}A default allocator is provided.T is the type of the object stored in the vector.Constructors for vector:
vector<int> ivec1;vector<int> ivec2(3,9);vector<int> ivec3(ivec2);
Containers : is empty?
Always use: if(icontainer.empty()) …Instead of if(icontainer.size() == 0)
For some containers, calculating size takes linear time.
COP 3330 Object Oriented Programming in C++ Lecture Slides 36/134 (c) pk
3
An example usage#include <vector>#include <iostream>
using namespace std;
int main() {vector<int> vec(10); // Creates a vector
// Initializes the vectorfor(int i=0; i< vec.size(); i++) {
vec[i] = rand() % 10;cout << " vec[" << i << "]=" << vec[i] << endl;
};return 0;
}
pk@linprog4:~>./a.outvec[0]=3vec[1]=6vec[2]=7vec[3]=5vec[4]=3vec[5]=5vec[6]=6vec[7]=2vec[8]=9vec[9]=1
An example usage#include <vector>#include <iostream>
using namespace std;
int main() {
vector<int> ivec;cout << ivec[0]; //errorvector<int> ivec2(10);// subscripts available: 0..9 cout << ivec[10]; // error
return 0;}
pk@linprog4:~>./a.outSegmentation fault (core dumped)
Make this your friend…
Iterators
Browsers for containers.Allows restricted access to objects stored in a container.Can be a class, data structure or an Abstract Data Type.
Iterators
A replacement for subscripting, for example in case of vectors: v[i]Subscripts are not available for all containers but iterators are.You can think of an iterator as pointing to an item that is part of a larger container of items.
Iterators
Container.begin() : All containers support a function called begin, which will return an iterator pointing to the beginning of the container (the first element) Container.end() : returns an iteratorcorresponding to having reached the end of the container. (Not the last element)
IteratorsSupport the following operations:
Operator * : Element at the current position (example: (*it)). You can use “->” to access object members directly from the iterator. (Like a pointer)Operator++ : Moves the iterator to the next element. Most iterators will also allow you to use “ - - ” for stepping back one element.Operator == and != : Compare two iteratorsfor whether they represent the same position (not the same element).Operator = : Assigns an iterator.
COP 3330 Object Oriented Programming in C++ Lecture Slides 37/134 (c) pk
4
Iterators
Vector iterator picture.
Reason for half-open range:Easy loopingEmpty containers begin() == end()
data
v.begin() v.end()
Iterators
Defining an iterator: std::class_name<template_parameters>::iterator name;Example:
std::vector<int>::iterator vit = myvec.begin();cout << (*vit) << endl;
Printing all elements of a container.std::container_type<template_parameter>::iterator pos;for ( pos = container.begin();
pos != container.end(); ++pos)cout << (*pos) << endl;
Iterators : Examples
using namespace std;
vector<int> myIntVector; // Add some elements to myIntVectormyIntVector.push_back(1); //adds an element to end of vector.myIntVector.push_back(4); myIntVector.push_back(8);
for(int y=0; y<myIntVector.size(); y++) { cout<<myIntVector[y]<<" "; //Should output 1 4 8
}
The non-STL way, using subscripts to access data:
Iterators: Examples
using namespace std; vector<int> myIntVector; vector<int>::iterator myIntVectorIterator;
// Add some elements to myIntVectormyIntVector.push_back(1); myIntVector.push_back(4); myIntVector.push_back(8);
for(myIntVectorIterator = myIntVector.begin(); myIntVectorIterator != myIntVector.end(); myIntVectorIterator++) {
cout<<*myIntVectorIterator<<" "; // Should output 1 4 8
}
Iterator Types
Input Iterator : read only, forward moves.Output Iterator : write only, forward moves.Forward Iterator: Both read/write with (++) supportBackward: Both read/write with (--) supportBi-Directional :Read write and Both ++ or –support.Random: Read/Write/Random access. (Almost act like pointers)
MostCommon
Iterators
Vector, dequeRandom access iterator
list, set, multiset, map, multimap
Bi-directional iterator
ostream_iterator, inserter, front_inserter, back inserter
Output Iterator
istream_iteratorInput Iterator
ExampleType of iterator
COP 3330 Object Oriented Programming in C++ Lecture Slides 38/134 (c) pk
5
Random Access Iterators
Allow arithmeticit+nThe result will be the element corresponding to the nth item after the item pointed to be the current iterator. it – n also allowed(it1 – it2) allowed
• Example: Type of this operation for vectors is defined by vector<T>::difference_type.
Back to vectorsIterator type: Random-access Operator [] overloaded
Removes the element at the iterator position pos and returns the position of the next element.
v.erase(pos)Another form:
v.erase(bpos,epos)
Inserts elem at position pos and returns the position of the new element.
v.insert(pos,elem)
Adds elem at end of vectorv.push_back( elem )
Removes last elementv.pop_back()
Removes all elementsv.Clear()
Number of elements in vectorv.size()
Back to vectors
Changes the size to new_size.v.resize(new_size)
Returns first , last element.v.front() , v.back()
Returns the element with index idx. Throws range error exception if idx is out of range.
v.at( idx )
Increases capacity to new_size.v.reserve(new_size)
Returns maximum number of elements without reallocation
v.capacity()
Maximum number of elements possible (in entire memory!).
v.max_size()
Important facts
For vectors, the C++ standard states:&v[i] = &v[0] + I
vector < char > vv;vv.push_back ( 'P' );vv.push_back ( 'Q' );vv.push_back ( 'R' );vv.push_back ( '\0' );printf("%s\n",&vv[0]);
Output : PQR
The swap trick.
To trim capacity, you can use the following trick:
std::vector<T>(v).swap(v);Makes capacity = size.
• Example: vector<int>(ivec2).swap(ivec2);
Important Facts
When deleting containers of newed/malloced elements, remember to delete/free them before deleting the container.Thread safety of STL containers:
Multiple readers are okMultiple writers to different containers are ok.
COP 3330 Object Oriented Programming in C++ Lecture Slides 39/134 (c) pk
6
What can a container contain?
Minimal constraint on elements of a container.
Operator= • a = b; should be valid
A copy constructor• YourType b(a); should be valid
Question :Is vector<int&> allowed?
Suggestions
Prefer vector and string to dynamically allocated arrays.Use reserve() to avoid unnecessary reallocations.Avoid using vector<bool>
Algorithms
Methods that act on containers (may or may not change them)
Examples: Sorting, searching, reversing etc.Examples:
• sort(v.begin(), v.end())• pos = find(v.begin(), v.end(), 3) // returns an
iterator in the container.• reverse(v.begin(), v.end())• unique(v.begin(), v.end()) // operates on a sorted
range to collapse duplicate elements.
Understand ComplexityExample: Vector Insert
What happens when the vector is large?
Intro To The Standard string Class
C++ has a standard class called "string"Strings are simply a sequence of characters
Note: This is not a sufficient definition for a "C-string"A "C-string" is an array of characters terminated by a null byte
Must #include <string> using the standard namespace to get C++ standard string functionality
Note: This is different from #include'ing <string.h> which is the header required for "C-string"s
string variables are used to store names, words, phrases, etc.Can be input using ">>" and output using "<<" as other types
Some string FunctionalityDeclaring a string:
string lastName;string firstName(“Piyush”); //Note: String literal enclosed in double quotesstring fullName;
Assigning a string:lastName = “Kumar”; //The usual assignment operator
Appending one string on the end of another:fullName = firstName + lastName; //Results in “PiyushKumar"fullName = firstName + " " + lastName; //Results in “Piyush Kumar"
Accessing individual characters in a string:myChar = firstName[4]; //Results in ‘s' (no bounds checking)myChar = firstName.at(4); //Results in ‘s' (does bounds checking)
Appending a character to the end of a string:lastName = lastName + myChar; //Results in “Kumars"
Determining number of characters in string:myInt = firstName.length(); //Results in 6
firstName[5] = ‘h’
firstName[6] is undefined unlike C where its ‘\0’.
COP 3330 Object Oriented Programming in C++ Lecture Slides 40/134 (c) pk
7
string Example #1
#include <iostream>#include <string>using namespace std;int main(void){string first;string last("Morgan");
first = "Drew"; //Would be illegal for C-stringcout << "Length of " << first << " is: " << first.length() << endl;cout << "Length of " << last << " is: " << last.length() << endl;
first += "Morgan";cout << "Length of " << first << " is: " << first.length() << endl;cout << "Length of " << last << " is: " << last.length() << endl;
first.assign("Drew");first.append(" ");first.append(last);cout << "Length of " << first << " is: " << first.length() << endl;cout << "Length of " << last << " is: " << last.length() << endl;return(0);
}
Length of Drew is: 4Length of Morgan is: 6Length of DrewMorgan is: 10Length of Morgan is: 6Length of Drew Morgan is: 11Length of Morgan is: 6
Constructors
string() // empty stringstring(string s) // copy of sstring(string s, int start) // substring start,endstring(string s, int start, int len) // substringstring(char* a) // copy of C-stringstring(int cnt, char c) // one or more charsstring(char* beg, char* end) // [beg, end)
Additional string Functionality
Strings can be compared with usual operators>, >= (greater than, greater than/equal to)<, <= (less than, less than/equal to)== (equality)
Strings also have a member function called "compare"int string::compare(string rhs);Return value is negative if calling string is less than rhsReturn value is positive if calling string is greater than rhsReturn value is zero if both strings are identical
Other overloaded operators
= is used to assign a value (char, C-string, or string) to a string.+= is used to append a string, character, or C-string to a string.+ is used to concatenate two strings or a string with something else<< and >> are used for input and output. On input, leading whitespace is skipped, and the input terminates with whitespace or end of file.
When you need a C-string
string s = “1234”;s.data() // returns s as a data array, no ‘\0’.s.c_str() // returns s as a C-string with ‘\0’int i = atoi(s.c_str()); // conversion// i is now 1234.
char *carray = new char[80];s.copy(carray, 79); // copies up to 79 char
String Operations
s.append(s2); // append s2 to ss.push_back(c); // append a chars.erase(various); // erases substringss.insert(various); // inserts substringss.clear(); // removes all contentss.resize(cnt); // change the size of s to cntswap(a, b); // for general containers.
COP 3330 Object Oriented Programming in C++ Lecture Slides 41/134 (c) pk
8
String Operations
s.replace(various); // replaces characters
s.size(); or s.length(); // how many characters?
s.max_size(); // maximum number of char?
s.empty(); // is s empty?s.reserve(cnt); // reserves memory
string Example #2int main(void){string s1 = "Drew";string s3;int result;
s3 = "Bob";if (s3 < s1)cout << "oper: s3 less than s1";
if (s3 > s1)cout << "oper: s3 greater than s1";
if (s3 == s1)cout << "oper: s3 is equal to s1";
cout << endl;
result = s3.compare(s1);if (result < 0)cout << "comp: s3 less than s1";
else if (result < 0)cout << "comp: s3 greater than s1";
elsecout << "comp: s3 is equal to s1";
cout << endl;
s3 = "Drew";if (s3 < s1)cout << "oper: s3 less than s1";
if (s3 > s1)cout << "oper: s3 greater than s1";
if (s3 == s1)cout << "oper: s3 is equal to s1";
cout << endl;
result = s3.compare(s1);if (result < 0)cout << "comp: s3 less than s1";
else if (result < 0)cout << "comp: s3 greater than s1";
elsecout << "comp: s3 is equal to s1";
cout << endl;
return (0);}
oper: s3 less than s1comp: s3 less than s1oper: s3 is equal to s1comp: s3 is equal to s1
Even More string Functionality
Getting a substring of a string:string string::substr(int startPos, int length)
• Returns the substring starting at "startPos" with length of "length"Finding the location of a substring within a string:
int string::find(string lookFor);• Returns the index where the first instance of "lookFor" was found in the string• Returns "string::npos" (which is usually -1) when the substring isn't found
int string::find(string lookFor, int startFrom);• Returns the index where the first instance of "lookFor" was found, starting the search
at the index "startFrom", or "string::npos" when the substring isn't foundFinding specific characters in a string:
int string::find_first_of(string charList, int startFrom);• Returns the index of the first instance of any character in "charList", starting the searc
at the index "startFrom", or "string::npos" if none of the chars are foundint string::find_first_not_of(string charList, int startFrom);
• Returns the index of the first instance of any character NOT in "charList", starting the search at the index "startFrom", or "string::npos" if none of the chars are found
string Example #3int main(){int startPos;int len;int commaLoc;int howLoc;int loc;int spaceLoc;string myStr;string myStr2;
myStr = "Hello, how are you?";startPos = 7;len = 3;myStr2 = myStr.substr(startPos, len);cout << "Substr: " << myStr2 << endl;commaLoc = myStr.find(",");howLoc = myStr.find(myStr2);cout << "Comma: " << commaLoc;cout << " how: " << howLoc << endl;
cout << "Spaces:";spaceLoc = myStr.find(" ");while (spaceLoc != string::npos){cout << " " << spaceLoc;spaceLoc = myStr.find(" ", spaceLoc + 1);
}cout << endl;
cout << "Punct and spaces:";loc = myStr.find_first_of(" ,?", 0);while (loc != string::npos){cout << " " << loc;loc = myStr.find_first_of(" ,?", loc + 1);
}cout << endl;
return (0);} Substr: how
Comma: 5 how: 7Spaces: 6 10 14Punct and spaces: 5 6 10 14 18
string Class ImplementationThe string class uses dynamic memory allocation to be sure segmentation faults don't occur
When a string is updated such that it requires more characters than currently allocated, a new, larger array is allocated and the prior contents are copied over as necessary
Since dynamic allocation is relatively slow, it is not desirable to be re-allocating strings often
C++ allows some memory to be "wasted" by often allocating more space than is really neededHowever, as strings are appended to the end, it is likely that a re-allocation won't be needed every timeOccasionally, re-allocation is necessary and is performed, again allocating more memory than necessary
Note: this is all done automatically by the string class ( Similar to vectors? )
Some Final string Functionality
Several member functions are available to get information about a string
capacity: The number of characters that can be placed in a string without the inefficiency of re-allocatinglength: The number of characters currently in the string
You can manually change the capacity of a stringresize: Sets the capacity of a string to be at least a user-defined sizeThis can be useful if you know a string will be at most ncharacters long
• By resizing the string to capacity n only that amount of memory is associated with the string
• This prevents wasted memory when you know the exact size you need
• Additionally, it can help prevent numerous re-allocations if you will be appending on to the end of the string, but know the final size ahead of time
COP 3330 Object Oriented Programming in C++ Lecture Slides 42/134 (c) pk
9
Example #4int main(void){string str;string str2;
cout << "Str: " << str << endl;cout << "Length: " << str.length();cout << " Cap: " << str.capacity();cout << endl;
str = "888";cout << "Str: " << str << endl;cout << "Length: " << str.length();cout << " Cap: " << str.capacity();cout << endl;
str += "-111-";cout << "Str: " << str << endl;cout << "Length: " << str.length();cout << " Cap: " << str.capacity();cout << endl;
str += "1723-9";cout << "Str: " << str << endl;cout << "Length: " << str.length();cout << " Cap: " << str.capacity();cout << endl;
str += "abcdefghijklmnopqrstuv";cout << "Str: " << str << endl;cout << "Length: " << str.length();cout << " Cap: " << str.capacity();cout << endl;
return (0);}Str:
Length: 0 Cap: 0Str: 888Length: 3 Cap: 31Str: 888-111-Length: 8 Cap: 31Str: 888-111-1723-9Length: 14 Cap: 31Str: 888-111-1723-9abcdefghijklmnopqrstuvLength: 36 Cap: 63
C Vs C++: Strings
.size( ) or .length( ) methods
strlen
.find( ) method
.rfind( ) methodstrchr, strstrstrrchr
= =, !=, <, >, <=, >=strcmp+=strcat= strcpy
C++ string operators /member functions.
C Library Functions
Reading text into a string
getline(istream, s); // Reads from istream (e.g., cin or a file) into the string s. Returns a reference to istream that can be used again.Reads all characters until a line delimiter or end of file is encountered.The line delimiter is extracted but not put into the stringYou can then parse s without worrying about end of line or end of file characters.
Char functions in C/C++
#include <ctype.h>int isalnum(int c); //non-zero iff c is alphanumericint isalpha(int c); //non-zero iff c is alphabeticint isdigit(int c); //non-zero iff c a digit: 0 to 9int islower(int c); //non-zero iff c is lower caseint ispunct(int c); //non-zero iff c is punctuationint isspace(int c); //non-zero iff c is a space charint isupper(int c); // non-zero iff c is upper caseint isxdigit(int c); //non-zero iff c is hexadecimalint tolower(int c); //returns c in lower case int toupper(int c); //returns c in upper case
Using the transform algorithm #include <algorithm>
Lowercase all characters of a string:transform(s.begin(), s.end(), // source
s.begin(), // destinationtolower); // operation
Uppercase all characters:transform(s.begin(), s.end(), s.begin(), toupper);
tolower and toupper are C-string functions. Other functions can also be used.
Using the transform algorithm #include <algorithm>
What does the following do?If (s == reverse(s.begin(),s.end()))
cout << “S is a …”;
COP 3330 Object Oriented Programming in C++ Lecture Slides 43/134 (c) pk
10
Solution to assignment 1
vector<string> vs_inpvec;string s_one_entry;int counter = 0;while( getline( cin, s_one_entry) ){
int _pos = s_one_entry.rfind('/');if(_pos != -1)
s_one_entry = s_one_entry.substr(_pos+1, s_one_entry.size() );
vs_inpvec.push_back(s_one_entry);}
What does this code do?
Solution to assignment 1sort(vs_inpvec.begin(), vs_inpvec.end());int i_inp_elements = vs_inpvec.size();cout << "Input Elements = " << i_inp_elements << endl;
vs_inpvec.erase(unique(vs_inpvec.begin(), vs_inpvec.end()) ,vs_inpvec.end()
);
int i_unique_elements = vs_inpvec.size();cout << "Unique Elements = " << i_unique_elements << endl;cout << "Duplicate Elements = " <<
i_inp_elements - i_unique_elements<< endl;
Reading assignment: Chapter 3, 9Including Bitset.
#include <bitset>
Ordered collection of bits.Example program
// create a bitset that is 8 bits long bitset<8> bs; // display that bitsetfor( int i = (int) bs.size()-1; i >= 0; i-- ) { cout << bs[i] << " "; } cout << endl;
// create a bitset out of a number bitset<8> bs2( (long) 131 ); // display that bitset, too for( int i = (int) bs2.size()-1; i >= 0; i-- ) { cout << bs2[i] << " "; } cout << endl;
0 0 0 0 0 0 0 01 0 0 0 0 0 1 1
bitset operators
!= returns true if the two bitsets are not equal. == returns true if the two bitsets are equal. &= performs the AND operation on the two bitsets. ^= performs the XOR operation on the two bitsets. |= performs the OR operation on the two bitsets. ~ reverses the bitset (same as calling flip()) <<= shifts the bitset to the left >>= shifts the bitset to the right [x] returns a reference to the xth bit in the bitset.
Example// create a bitset out of a number bitset<8> bs2( (long) 131 ); cout << "bs2 is " << bs2 << endl;
// shift the bitset to the left by 4 digits bs2 <<= 4; cout << "now bs2 is " << bs2 << endl;
Output?bs2 is 10000011 now bs2 is 00110000
Recommended Exercise:3.23, 3.21, 3.18, 3.15
COP 3330 Object Oriented Programming in C++ Lecture Slides 44/134 (c) pk
1
Pointers and Arrays
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Introduction To Pointers
A pointer in C++ holds the value of a memory addressA pointer's type is said to be a pointer to whatever type should be in the memory address it is pointing to
Just saying that a variable is a pointer is not enough information!Generic syntax for declaring a pointer:
dataType *pointerVarName;
Specific examplesint *iPtr; //Declares a pointer called "iPtr" that will
//point to a memory location holding an//integer value
float *fPtr; //Declares a pointer called "fPtr" that will//contain an address, which is an address of//a memory location containing a float value
The Operator &There is an operator, &
When this symbol is used as a unary operator on a variable it has a different meaning than as a binary operator or type specifierIt is unrelated to the "logical and", which is && or “bitwise and”, &It is unrelated to the use of & in regards to reference parameters
The operator & is usually called the "address of" operatorIt returns the memory address that the variable it operates on is stored at in memorySince the result is an address, it can be assigned to a pointer
Using The "Address Of" Operator
10081009
10111010
10071006100510041003100210011000
1000
i
iPtr
6int i = 6; //Declares an int, stored
//in memory somewhere//In this example, it is//stored at address 1000
int *iPtr; //Declares a pointer. The //contents of this variable//will point to an integer//value. The pointer itself//must be stored in memory, and//in this example, is stored at//memory location 1004
iPtr = &i; //Sets the iPtr variable to //contain the address of the//variable i in memory
The Operator *Like the &, the * operator has another meaning as wellThe * operator is usually referred to as the "dereference operator"The * operator operates on a pointer value
The meaning is "Use the value that this pointer points to, rather than the value contained in the pointer itself"
If a pointer is of type "int *" and the dereference operator operated on the pointer, the result is a value of type "int"Dereferenced pointers can be used as L-values or R-values
When used as an L-value (on the left side of an assignment), the pointer is unaffected, but the memory that it points to is changed
When a pointer that is pointing to memory you are not allowed to access is dereferenced, the result is a program crash via a "segmentation fault"
Using The Dereference Operator
10081009
10111010
10071006100510041003100210011000
1000
i
iPtr
6int i = 6; //Declares integer called iint *iPtr; //Declares a pointer to an int
iPtr = &i; //Sets the iPtr variable to //contain the "address of" the//variable i in memory
cout << "i: " << i << endl;cout << "i: " << *iPtr << endl;
*iPtr = 4; //Changes the memory being//pointed to by iPtr to contain//the value 4
cout << "i: " << i << endl;cout << "i: " << *iPtr << endl;
4
i: 6i: 6i: 4i: 4
COP 3330 Object Oriented Programming in C++ Lecture Slides 45/134 (c) pk
2
Arrays And PointersThe name of an array variable in C++, without the use of the [ ] operator, represents the starting address of the arrayThis address can be stored in a pointer variable
Since array values are guaranteed to be in contiguous memory, you can access array values using this one pointerExamples of this will come later, after discussing "pointer arithmetic"
const int NUM = 3;int iAry[NUM] = { 2, 4, 6 };int *iPtr;
iPtr = iAry; //Assigns iPtr to point//to the first integer//in the iAry array
//This cout prints the value of the//value stored in the location iPtr//points to (the first int in the//iAry, in this case)cout << "val: " << *iPtr << endl;
1023
1022
1021
1020
1019
1018
1017
1016
1015
1014
1013
1012
iAry[1]
iAry[0]
NUM
iPtr
iAry[2]
1008
1009
1011
1010
1007
1006
1005
1004
1003
1002
1001
1000
3
2
4
6
1004
val: 2
Pointer Arithmetic, Motivation
Incrementing the contents of an "int*" variable by one doesn't make sense
Integers require 4 bytes of storageIncrementing iPtr by 1, results in the pointer pointing to location 1005However, location 1005 is not an address that is the starting address of an integer
Dereferencing a pointer that contains an invalid memory location, such as 1005 may result in a Bus Error
When your program results in a bus error, the program crashes immediately (Segmentation fault).
1023
1022
1021
1020
1019
1018
1017
1016
1015
1014
1013
1012
iAry[1]
iAry[0]
NUM
iPtr
iAry[2]
1008
1009
1011
1010
1007
1006
1005
1004
1003
1002
1001
1000
3
2
4
6
1004
Pointer Arithmetic, Description
Recall that a pointer type specifies the type of value it is pointing toC++ can determine the size of the value being pointed toWhen arithmetic is performed on a pointer, it is done using this knowledge to ensure the pointer doesn't point to intermediate memory locationsIf an int requires 4 bytes, and iPtr is a variable of type "int *", then the statement "iPtr++;" actually increments the pointer value by 4Similarly, "iPtr2 = iPtr + 5;" stores the address "five integers worth" past iPtr in iPtr2
• If iPtr was 1000, then iPtr2 would contain the address 1020• 1020 = 1000 + 5 * 4
Pointer arithmetic is performed automatically when arithmetic is done on pointersNo special syntax is required to get this behavior!
Using Pointer Arithmeticconst int NUM = 3;int iAry[NUM] = { 2, 4, 6 };int *iPtr;int *iPtr2;int *iPtr3;int i;
iPtr = iAry; //Assigns iPtr to point//to the first integer//in the iAry array
iPtr3 = iAry;for (i = 0; i < NUM; i++){iPtr2 = iPtr + i;cout << i << " " <<
iAry[i] << " " << *iPtr2 << " " << *iPtr3 << " " << *(iPtr + i) << endl;
iPtr3++;}
0 2 2 2 21 4 4 4 42 6 6 6 6
1023
1022
1021
1020
1019
1018
1017
1016
1015
1014
1013
1012
iAry[1]
iAry[0]
NUM
iPtr
iAry[2]
1008
1009
1011
1010
1007
1006
1005
1004
1003
1002
1001
1000
3
2
4
6
1004
Other Variables
Static Allocation Of ArraysAll arrays discussed or used thus far in the course have been "statically allocated"
The array size was specified using a constant or literal in the codeWhen the array comes into scope, the entire size of the array can be allocated, because it was specified
You won't always know the array sizes when writing source codeConsider a program that modifies an imageAs the developer, you won't know what image size the user will useOne solution: Declare the image array to be 5000 rows by 5000 columns
• Problem #1: This likely wastes a lot of memory – if the user uses an image that is 250x250, then there are 24,937,500 unused pixels. If each pixel requires 4 bytes, this is almost 100 MB (megabytes!) of wasted space
• Problem #2: What if the user needs to edit an image that is 6000x6000? Your program will fail, and likely result in a crash
Dynamic Allocation Of Arrays
If an array is "dynamically allocated", then space is not reserved for the array until the size is determined
This may not be until the middle of a function body, using a value that is not constant or literalThe size may be input by the user, read from a file, computed from other variables, etc.
As memory is "claimed" using dynamic allocation, the starting address is provided, allowing it to be stored in a pointer variableSince pointers can be used to access array elements, arrays can be dynamically allocated in this wayDynamically allocated memory is claimed from the heap, as opposed to the stack
COP 3330 Object Oriented Programming in C++ Lecture Slides 46/134 (c) pk
3
The "new" OperatorA new operator is used to perform dynamic allocation
The operator is the "new" operatorThe new operator:
Attempts to find the amount of space requested from the heap"Claims" the memory when an appropriately sized available chunk of the heap is foundReturns the address of the chunk that was claimed
"new" can be used to allocated individual variables:iPtr = new int; //allocates an int variable
"new" can also be used to allocated arrays of variables:iPtr = new int[5]; //allocates an array of 5 integers
Array elements can be accessed using pointer arithmetic and dereferencing, or via the well-know [ ] operator, indexing an array
Static Vs Dynamic Allocation
int intArray[10];intArray[0] = 6837;
int *intArray;intArray = new int[10];intArray[0] = 6837;
...
delete[] intArray;
Stack allocation
Heap allocation
Code
Stack
Heap
Dynamic Allocation Of Arrays, Example
int i; //Loop variableint *iary; //This will be our array - an int pointerint num; //Length of the array (input from user)
cout << "Enter length of array: ";cin >> num;iary = new int[num]; //Dynamically declare an ary. Get
//necessary mem, assign address to iaryfor (i = 0; i < num; i++){
cout << "Enter int num " << i << ":";cin >> iary[i]; //use iary as if it were an array!
}
for (i = 0; i < num; i++){
cout << "Index " << i << ": " << iary[i] << endl;}
This fragment lets the user decide how big of an array is needed
Outputs Of Dynamic Allocation Example
Enter length of array: 7Enter int num 0:3Enter int num 1:1Enter int num 2:6Enter int num 3:8Enter int num 4:3Enter int num 5:2Enter int num 6:1Index 0: 3Index 1: 1Index 2: 6Index 3: 8Index 4: 3Index 5: 2Index 6: 1
Enter length of array: 3Enter int num 0:8Enter int num 1:4Enter int num 2:1Index 0: 8Index 1: 4Index 2: 1
Note: In the left example, the array required 28 bytes of memory (7 * 4). Exactly 28 bytes was allocated for the array.
In the right example, the array required only 12 bytes (3 * 4). Exactly 12 bytes was allocated for the array, and no extra memory was unused and wasted.
Another Dynamic Allocation Example
What is the likely result of the following program fragment?
int i; //Loop variableint *iary; //This will be our array - an int pointerint num; //Length of the array (input from user)
for (i = 0; i < 100000; i++){num = 50000;
iary = new int[num];
//Call a function to randomly fill the array//Do some sort of processing on the 50000 element ary//Do it again and again and again, accumulating stats.
}
Example Problem Description
The likely result would be that the program would be a failureThe reason is that the new operator claims the memory requested each iteration of the loopThere is only a finite amount of memory, though, and the amount requested is likely beyond the amount available
The problem is that while the memory is claimed, it is never released, of "freed", or "deleted"If you don't free the memory, but you do change the pointer pointing at it to point to a different address, then:
The original memory is still claimedThere is no way to access the original memory, since no pointers are pointing to itThe chunk of memory is wasted throughout the entire execution of the programThis is referred to as a "memory leak", and should be avoided
COP 3330 Object Oriented Programming in C++ Lecture Slides 47/134 (c) pk
4
Using The "delete" OperatorDynamically allocated memory can be released back into the available memory store using the "delete" operatorThe delete operator operates on a pointer and frees the memory being pointed to
Recall – a pointer may be pointing to a single value, or an array of valuesDue to this, the delete operator is used differently to delete single values and arrays
Deleting a single value being pointed to:delete iPtr;
Deleting an array of values being pointed to:delete [] iPtr;
Using the delete operator on a null pointer has no effectUsing the delete operator on a pointer pointing to memory that is not currently claimed by your program will cause a segmentation fault
Initialize all pointers to 0 (zero)Set all pointers to 0 after using the delete operator on them
Fixing The Memory Leak int i; //Loop variableint *iary; //This will be our array - an int pointerint num; //Length of the array (input from user)
for (i = 0; i < 100000; i++){
num = 50000;
iary = new int[num];
//Call a function to randomly fill the array//Do some sort of processing on the 50000 element ary//Do it again and again and again, accumulating stats.
delete [] iary; //No need to tell delete the size of //the array. This only frees up the//memory that iary is pointing to. It//does NOT delete the pointer in any way
}
Dynamically Allocating Objects
The arrow operator is another operator needed for working with pointers
The arrow operator is a dash and a greater than symbol: ->It is used to access public member variables or functions of an object that is being pointed to by a pointerIt is used the same way the dot operator is used on an actual object, but the arrow is used on a pointer variable instead
The arrow is used for convenienceAlternatively, you could deference the pointer and use the dot operator
Since the arrow operator implies a dereference, using the arrow operator on a pointer that doesn't point to claimed memory results in a segmentation fault!
Using The Arrow Operator ->
class CircleClass{public:
float x;float y;float z;float radius;
};
int main(){CircleClass myObj;CircleClass *myPtr;myPtr = &myObj;
myObj.x = 5;myPtr->y = 9;myObj.z = 15;myPtr->radius = 56.4;
...
I access the same memory location usingboth the actual object and a pointer to thatobject.
The dot operator is used with the object
The arrow operator is used with the pointer
Dynamically Allocating Objects
class TempClass{public: int ival;double dval;
};
int main(){TempClass *temp; //4 bytes (or sizeof(tempClass*)temp = new TempClass; //Claims enough space for all
//members of a tempClass object
temp->ival = 16; //Since temp is a pointer,temp->dval = 4.5; //the arrow operator is used
...
Note: The actual object that isallocated (the memory location)never gets a name! It is only pointedto by the temp pointer!
Using Constructors With Dynamic Allocation
Remember – a constructor is used whenever an object is allocated, whether statically or dynamically
class IntClass{public: int val;
IntClass() //Default ctor sets val to 0{val = 0;
}IntClass(int inVal) //Initializes val to value passed in{val = inVal;
}};
IntClass ic; //sets ic.val to 0IntClass *icPtr = new IntClass; //sets icPtr->val to 0
IntClass ic2(6); //sets ic2.val = 6IntClass *icPtr2 = new IntClass(10); //sets icPtr->val to 10
Uses thedefault ctor
Uses thevalue ctor
COP 3330 Object Oriented Programming in C++ Lecture Slides 48/134 (c) pk
5
The sizeof OperatorOften, you need to know how many bytes of memory a variable or type requires.Different architectures use different sizes.Use the sizeof operator to determine the current architecture's size of a var or type
int num; //Length of the array (input from user)cout << "sizeof(int): " << sizeof(int) << endl;cout << "sizeof(float): " << sizeof(float) << endl;cout << "sizeof(double): " << sizeof(double) << endl;cout << "sizeof(char): " << sizeof(char) << endl;cout << "sizeof(num): " << sizeof(num) << endl;
sizeof(int): 4sizeof(float): 4sizeof(double): 8sizeof(char): 1sizeof(num): 4
Result may vary on different machines!(These results are common)
Dynamically Alloc Mem in COperators "new" and "delete" don't exist in C, but C programmers still need dynamic allocation.Three important functions for C dynamic allocation
//malloc takes one parameter, size, which is simply//the number of bytes you are requesting.. Returns a//void *, which is a generic pointer to any type.void *malloc(size_t size);
//calloc initializes each ary element to 0. nelem is//the number of elements you are requesting, and //elsize is the number of bytes each element requires.void *calloc(size_t nelem, size_t elsize);
//free takes one param, which is a pointer to memory//that was previously allocated using malloc or callocvoid free(void *ptr);
Dynamically Alloc Mem in C Example
#include <stdlib.h>//---int *iary; //This will be our array - an int pointerint *iary2; //Another integer array.int num; //Length of the array (input from user)
cout << "Enter length of ary: ";cin >> num;
iary = (int *)malloc(num * sizeof(int)); //not init.iary2 = (int *)calloc(num, sizeof(int)); //init to 0
//Something useful happens here..
//Free up the memory now!free(iary);free(iary2);
Prefer C++ to C
string *stringarray1 = static_cast<string *> (malloc(10*sizeof(sting)) );string *stringarray2 = new string[10];
…
free (stringarray1); // no destructors called// What happened if string object reallocated stuff? Enlarged itself?delete[] stringarray2;
Use same form of new/delete
string *stringarray2 = new string[100];
…
delete stringarray2;// Program behavior undefined// At least the 99 strings are still in the memory somewhere Memory LEAK!
new/delete in constructors/destructors
For a class with dynamically allocated memory, Initialize pointers in constructors to 0. If unknown size, make them null.
Deleting a null pointer is always safe.Make sure you delete them all in the destructor.
COP 3330 Object Oriented Programming in C++ Lecture Slides 49/134 (c) pk
6
Out of memory errors#include <iostream>
using namespace std;
void OutOfMemory(){cerr << "No more memory\n";
abort();}
int main() {set_new_handler(OutOfMemory);double *pbigarray = new double[200000000];cout << "I am here\n";pbigarray[9999999] = 123;cout << pbigarray[999999] << endl;
return 0;}
Multidimensional Arrays
DefinitionType MDarray[size_1][size_2] ... [size_k]
What it meansk - dimensional arrayMDarray: array identifiersize_i: a positive constant expressionType: standard type or a previously defined user type and is the base type of the array elements
SemanticsMDarray is an object whose elements are indexed by a sequence of k subscriptsthe i-th subscript is in the range 0 ... size_i-1
Multi-dimensional Arrays
Multidimensional arrays are laid out in row-major orderConsiderint M[2][4];
M is two-dimensional array that consists of 2 subarrays each with 4 elements.
2 rows of 4 elements
The array is assigned to a contiguous section of memory
The first row occupies the first portionThe second row occupies the second portion
Multi-dimensional Arrays
© Art of Assemby website.
Multi-dimensional arrays
Example: int myImage[NROWS][NCOLS];
Can be used as parameter in a function prototype. Example:
void process_matrix( int in[ ][4], int out[ ][4], int nrows)void process_matrix( int in[4][4], int out[4][4], int nrows)
//Invalidvoid process_matrix( int in[][], int out[][], int nrows)
Multi-dimensional arrays
Really an array of arrays.
int main() {int x [3][4];int (*ip)[4]; // pointer to an array of 4 integersint *oip = &(x[0][0]);
ip = x;for (int i = 0 ; i < 3; ++i)for (int j = 0; j < 4; ++j)
x[i][j] = i*10 + j;
cout << (*ip)[0] << "\t" << (* (++ip) )[0] << endl;cout << * (++oip) << endl;return 0;
}
23222120
13121110
03020100
Recommended exercises: 5.9, 5.30, 5.14, 5.23
COP 3330 Object Oriented Programming in C++ Lecture Slides 50/134 (c) pk
7
Multi-dimensional Arrays
int (*matrix)[10];Pointer to an array of 10 integers
int *matrix[10];Array of 10 integer pointers.Example:
• int main( int argc , char *argv[])• argv[0] = “prgram name”• argv[1] = “../data/filename”• argv[2] = “2”
Buffer Overflow problems
3000000000
BBAAAAAAAALet A be a string and B be an integer.Changing A could change B!
/* overflow.c - demonstrates a buffer overflow */ #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) {
char buffer[10]; if (argc < 2) { fprintf(stderr, "USAGE: %s string\n", argv[0]); return 1;
}
strcpy(buffer, argv[1]); return 0;
}
Buffer Overflow problems
3000000000
BBAAAAAAAALet A be a string and B be an integer.Changing A could change B!
/* better.c - demonstrates one method of fixing the problem */ #include <stdio.h> #include <string.h>
int main(int argc, char *argv[]) { char buffer[10]; if (argc < 2) { fprintf(stderr, "USAGE: %s string\n", argv[0]); return 1;
}
strncpy(buffer, argv[1], sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; return 0;
}
Type conversions
C-Style castsfloat average = (float) sum / items;float average = (float) (sum/items);
C++ Stylestatic_cast< type >( identifier )float average = static_cast< float >( sum ) / items;float average = sum / static_cast< float >( items );
Type conversions
x=(float) i; cast in C++ - C notation
x=float(i); cast in C++, functional notation
x=static_cast<float>(i); ANSI C++ - recommended
i=reinterpret_cast<int>(&x) ANSI C++, not portable and system dependent
func(const_cast<int>(c_var)) where C_var is a const variable Used for removing “const-ness” when invoking func. Use with care.
static_cast
static_cast<T>(expression)The static_cast<>() is used to cast between the integer types.'eg' char->long, int->short etc.Static cast is also used to cast pointers to related types, for example casting void* to the appropriate type.
BaseClass_Employee* a = new DerivedClass_Manager(); static_cast<DerivedClass_Manager>(a)->derivedClassMethod();
COP 3330 Object Oriented Programming in C++ Lecture Slides 51/134 (c) pk
8
reinterpret_cast
float f = 2.5f;double * pd = reinterpret_cast<double*>(&f);
cout << f << endl << *pd << endl;
Outputs (!!!):
$ ./a.exe2.53.50861e+159
Reinterpret cast simply casts one type bitwise to another. Any pointer or integral type can be casted to any other with reinterpret_cast, easily allowing for misuse. static_cast will not be allowed in this case.
const_cast
const_cast<T>(expression)The const_cast<>() is used to add/remove const(ness) of a variable.
class A {public: void func() {} }; void f(const A& a) {
A& b = const_cast<A&>(a); b.func();
}
dynamic_cast
Dynamic cast is used to convert pointers and references at run-time, generally for the purpose of casting cast a pointer or reference up or down an inheritance chain (inheritance hierachy).
class Employee { ... }; class Manager : public Employee { ... };
void f(Employee* a) { Manager* b = dynamic_cast<Manager*>(a);
}
Type conversions
All Pointers can be converted to void *An explicit cast is required in C++ when you want to convert a void * to another pointer type.
char *char_p;void *generic_p;. . .generic_p=char_p; // OK, char* va in void*char_p=generic_p; // OK in C, illegal in C++char_p=static_cast<char *> (generic_p); // The C++ way.
Implicit conversions
char, short and bool are promoted to intInteger types which cannot be represented with an int are promoted to unsignedIn an expression with mixed type, lower order operand are promoted to the upper order, with the following rule:
• int < unsigned < long < unsigned long < float < double < long double
bool is an integer type, true is promoted to 1 and false to 0
COP 3330 Object Oriented Programming in C++ Lecture Slides 52/134 (c) pk
1
GDB
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
GDB
Lot of tutorials on google.Debugging tool, see what happens as your program runsNeeds the –g flag while compiling
This adds additional information (i.e. line numbers) in the binary executable
Execution:Invoke by typing “gdb <executable name>”E.g.: gdb a.out
Basic Commands
quitQuits gdb. Note that it is NOT exit…
runRun the program; it stops at each break point set by break command
x (address)Examine the CONTENTS of the memory at (address)
print (expression)Print the value of the expression - can be registers or simple equations
break (function name or *memory address)Set breakpointsE.g. : break main
break x.cpp:15
Basic Commandscontinue
Resume executionstep (s)
Step to the next line in CODE. Warning: If you use the step command while control is within a function that was compiled without debugging information, execution proceeds until control reaches a function that does have debugging information.
next (n)Similar to stepThis is similar to step, but function calls that appear within the line of code are executed without stopping.
disasShow assembly instructions for the current function
Basic Commands
where/btShows the current line and stack backtrace. Very useful for segmentation faults.
info registersShows the current state of the registers
display <var/register>display the contents of the register/var.E.g. : display count
display $eaxMore Commands:
http://sources.redhat.com/gdb/onlinedocs/gdb_toc.htmlGraphical User interface: dddScreen shots/movies : http://undo-software.com/undodb_screens.html
COP 3330 Object Oriented Programming in C++ Lecture Slides 53/134 (c) pk
1
Exceptions
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush KumarMaterial from “4th ed. Programming and Problem solving with C++, Dale, Weems.
Exceptions• Exceptions are run‐time anomalies, such as division by
zero, that require immediate handling when encountered by your program. The C++ language provides built‐in support for raising and handling exceptions. With C++ exception handling, your program can communicate unexpected events to a higher execution context that is better able to recover from such abnormal events.
• Useful when the code that detects the problem cannot handle it (Exception‐Detection code). Control must be transferred to the code that can handle such error. (Exception‐Handling code).
Exceptions in C++• Communication between exception‐detection and exception‐handling parts of the program in C++. It involves:• throw expressions• try blocks• exception classes
• The try, throw, and catch statements implement exception handling.
Exceptions in C++• If not handled properly, exceptions can cause the program
to :• Crash• Falls into unknown state
• An exception handler is a section of program code that is designed to execute when a particular exception occurs
• Resolve the exception• Lead to known state, such as exiting the program
Standard Exceptions
Exceptions Thrown by the Language
• newStandard Library RoutinesUser code, using throw statement
The throw StatementThrow: to signal the fact that an exception has occurred; also called raise
Syntax
throw Expression
COP 3330 Object Oriented Programming in C++ Lecture Slides 54/134 (c) pk
2
The try-catch Statement
tryBlock
catch (FormalParameter)Block
catch (FormalParameter)
TryCatchStatement
How one part of the program catches and processes the exception that another part of the program throws.
FormalParameterDataType VariableName
…
Example of a try-catch Statementtry
{// Statements that process personnel data and may throw// exceptions of type int, string, and SalaryError
}catch ( int ){
// Statements to handle an int exception}catch ( string s ){
cout << s << endl; // Prints "Invalid customer age"// More statements to handle an age error
}catch ( SalaryError ){
// Statements to handle a salary error}
Execution of try-catch
Nostatements throw
an exception
Statement following entire try-catch
statement
Astatement throws
an exception
ExceptionHandler
Statements to deal with exception are executed
Control moves directly to exception handler
Throwing an Exception to be Caught by the Calling Code
void Func4(){
if ( error )throw ErrType();
}
Normalreturn
void Func3(){
try{
Func4();
}catch ( ErrType ){
}
}
Functioncall
Return fromthrown exception
Practice: Dividing by ZEROApply what you know:
int Quotient(int numer, // The numerator
int denom ) // The denominator
{
if (denom != 0)
return numer / denom;
else
//What to do?? do sth. to avoid program //crash
}
int Quotient(int numer, // The numerator
int denom ) // The denominator
{
if (denom == 0)
throw DivByZero();
//throw exception of class DivByZero
return numer / denom;
}
A Solution
COP 3330 Object Oriented Programming in C++ Lecture Slides 55/134 (c) pk
3
A Solution// “quotient.cpp”-- Quotient program
#include<iostream>#include <string>
using namespace std;
int Quotient(int, int);
class DivByZero // Exception class
{};
int main()
{
intnumer; // Numerator
intdenom; // Denominator
cout << "Enter numerator and denominator: ";
cin >> numer >> denom;
while (cin){try{
cout << "Their quotient: "
<< Quotient(numer, denom) << endl;
}
catch (DivByZero)
{
cout << "*** Denominator can't be 0"
<< endl;
}
cout << "Enter numerator and denominator: ";
cin >> numer >> denom; }return 0;
}
int Quotient(/* in */ intnumer, // The numerator
/* in */ intdenom) // The denominator
{
if (denom == 0)
throw DivByZero();
return numer/ denom;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 56/134 (c) pk
1
Functions
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Functions in C++
Declarations vs Definitions Inline FunctionsClass Member functionsOverloaded FunctionsPointers to functionsRecursive functions
What you should know?
Defining a function
// return the greatest common divisorint gcd(int v1, int v2){
while (v2) {int temp = v2;v2 = v1 % v2;v1 = temp;
}return v1;
}
function gcd(a, b) if b = 0 return a else return gcd(b, a mod b)
Gcd Example1071,10291029, 4242, 2121, 0
Function body is a scope
Another scope.temp is a local variable
Non-reference parameter.
Calling a function?#include <iostream>
using std::cout;using std::endl;using std::cin;
int main(){
// get values from standard inputcout << "Enter two values: \n";int i, j;cin >> i >> j;
// call gcd on arguments i and j// and print their greatest common divisorcout << "gcd: " << gcd(i, j) << endl;return 0;
}
Function return types
// missing return typeTest(double v1, double v2){ /* … */ }
int *foo_bar(void){ /* … */ }
void process ( void ) { /* … */ }
int manip(int v1, v2) { /* … */ } // error
int manip(int v1, int v2) { /* … */ } // ok
Parameter Type-Checking
gcd(“hello”, “world”);gcd(24312);gcd(42,10,0);
gcd(3.14, 6.29); // ok?
// Statically typed language
COP 3330 Object Oriented Programming in C++ Lecture Slides 57/134 (c) pk
2
Pointer Parameters#include <iostream>#include <vector>using std::vector;using std::endl;using std::cout;
void reset(int *ip){
*ip = 0; // changes the value of the object to which ip pointsip = 0; // changes only the local value of ip; the argument is unchanged
}
int main(){
int i = 42;int *p = &i;
cout << "i: " << *p << '\n'; // prints i: 42reset(p); // changes *p but not pcout << "i: " << *p << endl; // ok: prints i: 0return 0;
}
Const parameters
Fcn(const int i) {}…Fcn can read but not write to i.
Reference Parameters// vec is potentially large, so copying vec might be expensive// use a const reference to avoid the copyvoid print(const vector<int> &vec){
for (vector<int>::const_iterator it = vec.begin();it != vec.end(); ++it) {
if (it != vec.begin()) cout << " ";cout << *it;
}cout << endl;
}
int main(){
vector<int> vec(42);print(vec.begin(), vec.end()); // Defined on next slideprint(vec);
}
Can be used toreturn information
Passing Iterators
// pass iterators to the first and one past the last element to printvoid print(vector<int>::const_iterator beg,
vector<int>::const_iterator end){
while (beg != end) {cout << *beg++;if (beg != end) cout << " "; // no space after last element
}cout << endl;
}
Const references
// When you don’t what the function to modify the value associated with // the reference
bool isShorter(const string &s1, const string &s2){return s1.size() < s2.size();
}
Passing reference to a pointer
// swap values of two pointers to intvoid ptrswap(int *&v1, int *&v2){
int *tmp = v2;v2 = v1;v1 = tmp;
}
// v1 and v2 are the pointers passed to ptrswap themselves, // just renamed
// The following link is out of the reach of this course:// Reading C/C++ declarations: http://www.unixwiz.net/techtips/reading-cdecl.html
COP 3330 Object Oriented Programming in C++ Lecture Slides 58/134 (c) pk
3
Array parameters
void printvalues(const int ia[10]);Parameter treated as “const int *”
No return values?
void swap (int &v1, int &v2);
Returning from main
#include <cstdlib>int main(){
bool some_failure = false;if (some_failure)
return EXIT_FAILURE;else
return EXIT_SUCCESS;}
Returning a reference#include <string>using std::string;#include <iostream>using std::cout; using std::endl;
//inline version: find longer of two stringsinline const string &shorterString(const string &s1, const string &s2){
return s1.size() < s2.size() ? s1 : s2;}
int main(){
string s1("successes"), s2("failure");cout << shorterString(s1, s2) << endl;
return 0;}
Tip 1: Never return a referenceto a local object.
Tip 2: Never return a pointerto a local object.
Put these in headerfiles.
Recursion
Recursion is the process a procedure goes through when one of the steps of the procedure involves rerunning the entire same procedure.
Fibonacci number sequence: F(n) = F(n − 1) + F(n − 2).
Recursion
function factorial(n) { if (n <= 1) return 1; else return n * factorial(n-1);
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 59/134 (c) pk
4
Recursion Recursion
template <typename T>void recSort(T begin, T end){
int len = distance(begin,end);if( len <= 1) return;
for(int i = 1; i < len; ++i)if(*(begin+i) < *(begin))
swap( *(begin+i) , *(begin) );recSort(begin+1,end);
}
int main() {vector<int> vs;int N = 10;
for(int i = 0; i < N; ++i)vs.push_back(rand());
recSort(vs.begin(), vs.end());for(int i = 0; i < N; ++i)
cout << vs[i] << endl;return 0;
}
Recursion
template <typename T>void recSort(T begin, T end){int len = distance(begin,end);if( len <= 1) return;
for(int i = 1; i < len; ++i)if(*(begin+i) < *(begin))
swap( *(begin+i) , *(begin) );
recSort(begin+1,end);
}
void recSort(vector<int>::iterator begin, vector<int>::iterator end){
int len = distance(begin,end);if( len <= 1) return;
for(int i = 1; i < len; ++i)if(*(begin+i) < *(begin))
swap( *(begin+i) , *(begin) );
recSort(begin+1,end);}
Generates
Can you see the recursion in a Sudoku solver?
Recursion
Another example.void printNum(int n){
if (n >= 10) printNum(n/10); print(n%10);
}
Another version.
void printNumB(int n, int b){
if (n >= b) printNumB(n/b); print(n%b);
}
Recursion
Eight Queens problem:Brute force solution: 64^8 = 2^48 = 281,474,976,710,656 possible blind placements of eight queens,
The eight queens puzzle is based on the problem of putting eight chess queens on an 8×8 chessboard such that none of them is able to capture any other using the standard chess queen's moves.
Recursion
Invariants:no two pieces can share the same row any solution for n queens on an n×mboard must contain a solution for n−1 queens on an (n−1)×m board proceeding in this way will always keep the queens in order, and generate each solution only once.
COP 3330 Object Oriented Programming in C++ Lecture Slides 60/134 (c) pk
5
Backtracking
A strategy for guessing at a solution and backing up when an impasse is reachedRecursion and Backtracking can be used together to solve our problem (and many other problems)
Eight Queens
An observation that eliminates many arrangements from consideration
No queen can reside in a row or a column that contains another queen
• Now: only 40,320 (8!) arrangements of queens to be checked for attacks along diagonals
Eight Queens
A recursive algorithm that places a queen in a column
Base case• If there are no more columns to consider
• You are finished
Recursive step• If you successfully place a queen in the current
column• Consider the next column
• If you cannot place a queen in the current column• You need to backtrack
The Eight Queens Problem
Figure 5.1 a) Five queens that cannot attack each other, but that can attack all of column 6; b) backtracking to
column 5 to try another square for the queen; c) backtracking to column 4 to try another square for the queen and
then considering column 5 again
Default Arguments
int ff(int i = 0);screen = screenInit( string::size_type height = 24,
string::size_type width = 80,char background = ‘ ‘ );
string screen = screenInit();string screen = screenInit(66);string screen = screenInit(66,256);string screen = screenInit(66,256,’#’); string screen = screenInit(,,’?’); // errorstring screen = screenInit(’?’); // calls (‘?’,80,’ ‘);
You can also call functions to initialize defaultArguments. These functions are called when the function is called.
Static variables.
Retain their values across function calls.In this course you are barred from using them.
COP 3330 Object Oriented Programming in C++ Lecture Slides 61/134 (c) pk
6
Function overloading
Functions having same name but different parameter types.
Record lookup(const Account&);Record lookup(const Phone&);Record lookup(const Name&);Record lookup(const SS&);
COP 3330 Object Oriented Programming in C++ Lecture Slides 62/134 (c) pk
1
Classes: Methods, Constructors, Destructors and Assignment
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Classes: Member functions// classes example#include <iostream>using namespace std;
class Square {int x;
public:int area () {return (x*x);};void set_values(int a);int get_sidelen(void) const;
};void Square::set_values(int a){ x = a; };int Square::get_sidelen(void) const { return x;}
int main () {Square s;s.set_values (3);cout << "area: " << s.area();return 0;
}
Member functions: Methods
private members of a class are accessible only from within other members of the same class or from their friends. protected members are accessible from members of their same class and from their friends, but also from members of their derived classes. Finally, public members are accessible from anywhere where the object is visible.
Objects : Reminder
An object is an instance of a class.Memory is allocated for each object instantiated (and not for the class).
Example: • Square S; // S is an object of Square class. (on stack)
• Square *pS = new Square; // on heap.
An object of a class can be defined in the same way as an internal type.
Objects : Reminder
Multiple objects of a class can be created (as many as you want). All the objects share the same copy of member functions.But, they maintain a separate copy of data members.
Square s1,s2; // each has separate copy of x
Objects: Reminder
The data members and member functions of an object have the same properties as the data members and member functions of its class.
COP 3330 Object Oriented Programming in C++ Lecture Slides 63/134 (c) pk
2
Assignment operator
Square s3 = s2;By default, copying a class object is equivalent to copying all its elements including pointers.
Variable assignment
Values are assigned to variables and not to their data types.Hence, you assign values to members of an object and not a class.Must create a unique object of a class because you cannot assign values to a class.
Square = 5 is meaningless…
Back to member functions
The member functions in the public section of a class can be accessed using the “.” operator for instantiated objects. (For pointers its -> )
Square s1, *s2;s1.set_values(5);s2 = new Square; s2->set_values(10);delete s2;
Member functions
Only the public members of an object can be directly accessed.
Special Member functions
Constructors: Are invoked to initialize the data members of a class. Can not return any value (not even void).
Can accept any parameters as needed.
What would happen if we called the member function area() before having called function set_values()?
Constructors & Destructors
Constructors initialize the objects in your class. Destructors cleans up and frees memory you may have allocated when the object was created.
COP 3330 Object Oriented Programming in C++ Lecture Slides 64/134 (c) pk
3
Constructors
Differs from other member functions.Initializes a newly created object.Other member functions are invoked by existing objects.A Constructor is invoked automatically when an object is created.
Constructors
Have the same name as the class.// classes example#include <iostream>using namespace std;
class Square {int x;
public:Square(int w){ x = w; };int area () {return (x*x);};void set_values(int a);int get_sidelen(void) const;
};void Square::set_values(int a){ x = a; };int Square::get_sidelen(void) const { return x;}
int main () {Square s(3);cout << "area: " << s.area();return 0;
}
Constructors
Have the same name as the class.class Square {
int x;public:
Square(){ x = 0; };int area () {return (x*x);};void set_values(int a);int get_sidelen(void) const;
};void Square::set_values(int a){ x = a; };int Square::get_sidelen(void) const { return x;}
int main () {Square s;cout << "area: " << s.area();return 0;
}
Default constructor is defined for you: Square(){};
Constructors: Overloading
You can have several constructors for a class by overloading them.
class Square {int x;
public:Square(int w){ x = w; };Square() { x = 0; };int area () {return (x*x);};void set_values(int a);int get_sidelen(void) const;
};
Constructors : Initialization
Prefer initialization to assignmentSquare(int w):x(w){};Array(int lowbound, inthighbound):size(highbound-lowbound+1), lb ( lowbound ), hb(highbound), data_vector(size) {}; // Problematic? Why?
List members in an initialization list in the order they were declared.
Constructors: Warning
If you implement no constructor, the compiler automatically generates a default constructor for youBut if you write any constructors at all, the compiler does not supply a default constructor.
COP 3330 Object Oriented Programming in C++ Lecture Slides 65/134 (c) pk
4
Copy Constructors
Gets called in a number of situations.If you do not write one, the compiler automatically generates one for you.
Copy constructors: When is it called?
When the return value of a function has class type.
Fraction process_fraction (int i, int j);When an argument has class type. A copy of the argument is made and passed to the function
int numerator_process (Fraction f);When you use one object to initialize another object.
Fraction a(1,3); Fraction b(a);
Copy constructors
Not passed when a pointer to an object is passed. It’s only called when a new copy of an existing object needs to be created.
Copy constructors
The syntax:class_name(class_name const &source)
Const: Making a copy should not alter source.&: The function should not need to call another copy constructor!
Copy Constructors: Example.
class Point {int x,y;
public:int xx(void) const { return x;};int yy(void) const { return y;};Point(Point const &p){
this->x = p.xx();this->y = p.yy();
};};
Destructors
You can have many constructors but only one destructor.The destructor must have the same name as the class, but preceded with a tilde sign (~) and it must also return no value. The use of destructors is especially suitable when an object assigns dynamic memory during its lifetime and at the moment of being destroyed we want to release the memory that the object was allocated.
COP 3330 Object Oriented Programming in C++ Lecture Slides 66/134 (c) pk
5
// example on constructors and destructors (from cplusplus.com)#include <iostream> using namespace std;
class CRectangle { int *width, *height;
public: CRectangle (int,int); ~CRectangle (); int area () {return (*width * (*height));}
};
CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b;
}
CRectangle::~CRectangle () { delete width; delete height; } int main () {
CRectangle rect (3,4), rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
Pointers to functions
Not in syllabus.
this pointer
Useful when a member function manipulates two or more objects.It holds the address of the object for which the member function is invoked.It is always passed to a non-static member function. This ensures the right object is updated using member functions.
Back to destructor example
What will happen if we do:CRectangle r1(10,20),r2(30,40);r1 = r2;The default assignment operator generated by the compiler is called. What is wrong with that in this example?
// example on constructors and destructors (from cplusplus.com)#include <iostream> using namespace std;
class CRectangle { int *width, *height;
public: CRectangle (int,int); ~CRectangle (); int area () {return (*width * (*height));}
};
CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b;
}
CRectangle::~CRectangle () { delete width; delete height; } int main () {
CRectangle rect (3,4), rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0;
}
Assignment operators
int x; x = 4;4 = x? // non-lvalue in assignmentx = y = z = 8;
Z is assigned 8 firstY is then assigned the value of returned by (z = 8) which is 8.x is now assigned the value returned by (y = 8) which is 8
COP 3330 Object Oriented Programming in C++ Lecture Slides 67/134 (c) pk
6
Assignment operators
Complex x, y, z; x = (y = z); Writing this in equivalent functional form:x.operator=(y.operator=(z));
Assignment operators
Square s1 = s2;The default behavior : Performs simple member by member copy.
(This is the one generated by the compiler)
Is the assignment operator the same thing as copy constructor?
Assignment Operator
Copy constructor initializes an object.Assignment operator copies values to an existing object.
Hence, in some cases: Copy constructor has to do more work than assignment operator.
Assignment Operator
The syntax:class_name& operator=(const class_name &source)
Const: Making an assignment should not alter source.&: The function should not need to call a copy constructors.
#include <iostream>#include <string.h>
using namespace std;
class Buf{public:
Buf( char* szBuffer, size_t sizeOfBuffer );Buf& operator=( const Buf & );void Display() { cout << buffer << endl; }
private:char* buffer;size_t SizeOfBuffer;
};
An ExampleBuf::Buf( char* szBuffer, size_t sizeOfBuffer ){
sizeOfBuffer++; // account for a NULL terminator
buffer = new char[ sizeOfBuffer ];if (buffer){
memcpy( buffer, szBuffer, sizeOfBuffer );SizeOfBuffer = sizeOfBuffer;
}}
Buf& Buf::operator=( const Buf &otherbuf ){
if( &otherbuf != this ){
if (buffer)delete [] buffer;
SizeOfBuffer = strlen( otherbuf.buffer ) + 1;buffer = new char[SizeOfBuffer];memcpy( buffer, otherbuf.buffer, SizeOfBuffer );
}return *this;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 68/134 (c) pk
7
int main(){
Buf myBuf( "my buffer", 10 );Buf yourBuf( "your buffer", 12 );
// Display 'my buffer'myBuf.Display();
// assignment opperatormyBuf = yourBuf;
// Display 'your buffer'myBuf.Display();
}
Guidelines
Place the common code used by the assignment operator and the copy constructor in a separate function and have each one call the function. This will make your code more compact and avoid duplication.A String class must copy a character string during the copy constructor and during an assignment. If we place this common code into a private member functionvoid CopyString(const char* ptr); then both the copy constructor and assignment operator may call this routine to perform the copy rather than duplicate this code in each.
From: http://www.acm.org/crossroads/xrds1-4/ovp.html
Guidelines
If your class has pointer data, you must provide an assignment operator. If writing an assignment operator, you must also write a copy constructor.The generated assignment operator performs member-wise assignment on any data members of your class. For pointer variables, we almost always do not want this because the data members of the copy will point to the same data as the copied object! Worse, if one of the objects is destroyed, the data is destroyed with it. A run-time error will occur the next time the remaining object tries to access the now non-existent data.
Guidelines
Always implement the assignment operator for your class; do not let the compiler generate the default assignment operator.The compiler will generate a default assignment operator for your class if you do not provide one. In order to be in complete control of how your class operates, always provide an assignment operator.
Guidelines
Check for assignment to self.Disaster can result if a variable is assigned to itself. Consider:X x; x = x; Suppose class X contains pointer data members that are dynamically allocated whenever an object is created. Assignment always modifies an existing object. The dynamic data will, therefore, be released before assigning the new value. If we do not check for assignment to self, the above assignment will delete the existing pointer data, and then try to copy the data that was previously deleted!
Guidelines
The destructor must release any resources obtained by an object during its lifetime, not just those that were obtained during construction.Make the constructor as compact as possible to reduce overhead and to minimize errors during construction.
COP 3330 Object Oriented Programming in C++ Lecture Slides 69/134 (c) pk
1
Classes II: Type Conversion, Friends, …
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Abstraction and Encapsulation
Abstraction: Separation of interface from implementationEncapsulation: Combining lower level elements to form higher-level entity.Access Labels (public/private/protected) enforce abstraction and encapsulation.
Concrete Types.
A concrete class is a class that exposes, rather than hides, its implementationExample : pair<> (defined in <utility>)Exists to bundle two data members.Example:
//-- Declare a pair variable. pair<string, int> pr1; //-- Declare and initialize with constructor. pair<string, int> pr2("heaven", 7); cout << pr2.first << "=" << pr2.second << endl; // Prints heaven=7
Benefits of Abstraction & Encapsulation
Class internals are protected from user-lever errors.Class implementation may evolve over time without requiring change in user-level code.
More on Class definitions
class Screen {public:
private: std::string contents;std::string::size_type cursor;std::string::size_type height,width;
…
Using Typedefs to streamline classes.
class Screen {public:
typedef std::string::size_type index;private:
std::string contents;index cursor;index height,width;
…}
inline Screen::index Screen::get_cursor() const{return cursor;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 70/134 (c) pk
2
Class declaration
class Screen; // declaration of the classForward declaration: Introduces the name Screen into the program and indicates that Screen refers to a class name.Incomplete Type: After declaration, before definition, Screen is an incomplete type. It’s known screen is a type but not known what members that type contains.
Class declaration for class members.
Because a class is not defined until its class body is complete, a class cannot have data members of its own type.A class can have data members that are pointers or references to its own type.
class Human {Screen window;Human *bestfriend;Human *father, *mother;…
}
Using this pointer
How do we implement the Screen class so that the following is allowed:
myScreen.move(4,0).set(‘#’)Equivalent to: myScreen.set(4,0); myScreen.set(‘#’)
Using this pointer
Return reference to Screen in the member functions.
Screen& move(index r, index c);Screen& set(char);Implementation:
• Screen& Screen::move(index r,index c){index row = r* width; cursor = row +c;return *this;
}
Using this pointer
Beware of const:const Screen& Screen::display(ostream &os) const {
os << contents; return *this;
}myScreen.move(4,0).set(‘#’).display(cout)
Mutable data members
“Sometimes”, you might want to modify a variable inside a const member function.A mutable data member is a member that is never const (even when it is a member of a const object).
COP 3330 Object Oriented Programming in C++ Lecture Slides 71/134 (c) pk
3
Mutable data members
class Screen {public:
private:mutable size_t access_ctr;
};
void Screen::do_display(std::ostream& os) const {++access_ctr; // keep count of calls to any member func.os << contents;
}
Guideline.
Never repeat code.If you have member functions that need to have repeated code, abstract it out in another function and make them call it (maybe inline it).
Type conversion: Revisited
int i; float f; f = i; // implicit conversion f = (float)i; // explicit conversion f = float(i); // explicit conversion
Type conversions: revisited
Can convert from one type into “this”type with constructor
Bitset( const unsigned long x );How do we convert from “this” type to something else?
Create an operator to output the other typeLater.
Implicit Type conversion
A constructor that can be called with a single argument defines an implicit conversion from the parameter type to the class type.
Class Sales_item {Public:
Sales_item(const std::string &book = “ “): isbn (book), units_sold(0), revenue(0.0) {}
…}
String null_book = “9-999-9999-9”; Item.sale_isbn(null_book); // implicit type conversion..
Beware:
class String { public:
String( int length ); // Allocation constructor // ...
};
// Function that receives an object of type String as an argument void foo( const String& aString );
// Here we call this function with an int as argument int x = 100; foo( x ); // Implicit conversion: foo( String( x ) );
COP 3330 Object Oriented Programming in C++ Lecture Slides 72/134 (c) pk
4
Use of implicit type conversion
class String { public:
String( char* cp ); // Constructor operator const char* () const; // Conversion operator to const char* // ...
};
void foo( const String& aString ); void bar( const char* someChars );
// main.ccint main() {
foo( "hello" ); // Implicit type conversion char* -> String String peter = "pan"; bar( peter ); // Implicit type conversion String -> const char*
}
Suppressing implicit conversions.
Use “explicit” before conversion constructors.
explicit String( char* cp ); // Constructor
Friends.
friend function/classesCan access private and protected (more later) members of another classfriend functions are not member functions of class
• Defined outside of class scopeA Friend declaration begins with the keyword “friend”
Friends
PropertiesFriendship is granted, not takenNOT symmetric
• if B a friend of A, A not necessarily a friend of B
NOT transitive • if A a friend of B, B a friend of C, A not necessarily a
friend of C.
Friends– friend declarations
friend function • Keyword friend before function prototype in
class that is giving friendship. – friend int myfunc( int x ); – Appears in the class granting friendship
friend class• Type friend class Classname in class
granting friendship• If ClassOne granting friendship to ClassTwo,
friend class ClassTwo; appears in ClassOne's definition
Friends
Why use friends?to provide more efficient access to data members than the function callto accommodate operator functions with easy access to private data members
Be careful: Friends can have access to everything, which defeats data hiding.Friends have permission to change the internal state from outside the class. Always use member functions instead of friends to change state
COP 3330 Object Oriented Programming in C++ Lecture Slides 73/134 (c) pk
5
An example#include <iostream>#include <string>
class Sales_item {friend bool operator==(const Sales_item&, const Sales_item&);friend std::istream& operator>>(std::istream&, Sales_item&);friend std::ostream& operator<<(std::ostream&, const Sales_item&);
// other members as beforepublic:
// added constructors to initialize from a string or an istreamSales_item(const std::string &book):
isbn(book), units_sold(0), revenue(0.0) { }Sales_item(std::istream &is) { is >> *this; }
public:// operations on Sales_item objects// member binary operator: left-hand operand bound to implicit this pointerSales_item& operator+=(const Sales_item&);// other members as before
…
COP 3330 Object Oriented Programming in C++ Lecture Slides 74/134 (c) pk
1
Introduction to Data Structures
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Sorted Arrays As ListsArrays are used to store a list of valuesArrays are contained in contiguous memory
Recall – inserting a new element in the middle of an array requires later elements to be "shifted". For large lists of values, this is inefficient.
void insertSorted(int value, int &length, int list[]){
int i = length - 1;while (list[i] > value){list[i + 1] = list[i];i--;
}list[i + 1] = value;length++;
}
Shifting array elements that come after the element being inserted
37291384
8 13 29 3764
Insert 6
Sorted ArraysDue to the need to "shift" elements, sorted arrays are:
Inefficient when inserting into the middle or frontInefficient when deleting from the middle or frontEfficient for searching
Since inserting and deleting are common operations, we need to find a data structure which allows more efficiency
Contiguous memory will not work – will always require a shift"Random" placement requires "random" memory locationsDynamic allocation provides "random" locations, and means that the list can grow as much as necessaryThe maximum size need not be known – ever
• This is not true for arrays, even dynamically allocated arrays
Intro To Linked Lists
A linked list is a data structure which allows efficient insertion and deletion.Consists of "nodes". Each node contains:
A value - the data being stored in the listA pointer to another (the next) node
By carefully keeping pointers accurate, you can start at the first node, and follow pointers through entire list.Graphically, linked list nodes are represented as follows:
value ptr
Linked List InfoEach node is dynamically allocated, so memory placement is "random"
100010041008100C101010141018101C102010241028102C103010341038
2 4 6
6*0
2*1030
*1010
4*1004
"start"
"start"
The above linked list maybe stored in memory asshown to the right.
Deletion From Linked Lists• Given the initial linked list:
2 4 6 8 10
Delete node with value 4
2 4 6 8 10
Resulting in
6 8 102
COP 3330 Object Oriented Programming in C++ Lecture Slides 75/134 (c) pk
2
Insertion Into Linked ListsGiven the initial linked list:
2 4 6 8 10
Insert node with value 5
Resulting in
2 4 6 8 10
5
2 4 6 8 105
Linked List Nodes, Example• Use a class to group the value and the pointer
class ListNodeClass{public: // Only for illustration: Bad design
int val; //Will have a list of intsListNodeClass *next; //Point to the next node
};
int main(){ListNodeClass *head = 0; //Essentially, this declares a
//list, since it will point to the//first node of a list. Initially,//list is empty (null pointer)
head = new ListNodeClass; //Note no [] - not //declaring an array - just//one single node
...
Printing a List (Visiting Each Node)
void printList(ListNodeClass *head){ListNodeClass *temp = head;
if (temp == 0){cout << "List is Empty!" << endl;
}else{while (temp != 0){
cout << temp->val << " ";temp = temp->next;
}cout << endl;
}}
Try To Insert To Front Of Listbool insertAtHead1(ListNodeClass *head,
int newVal){bool status = true;ListNodeClass *temp;
temp = new ListNodeClass;if (temp == 0){cout << "Unable to alloc node"
<< endl;status = false;
}else{temp->val = newVal;
if (head == 0){temp->next = 0;head = temp;
}
else{temp->next = head;head = temp;
}}return (status);
}int main(void){ListNodeClass *head1 = 0;printList(head1);insertAtHead1(head1, 5);insertAtHead1(head1, 8);insertAtHead1(head1, 17);printList(head1);return (0);
}
List is Empty!List is Empty!
Corrected Insert To Front Of List
bool insertAtHead(ListNodeClass **head, int newVal)
{bool status = true;ListNodeClass *temp;
temp = new ListNodeClass;if (temp == 0){cout << "Unable to alloc node"
<< endl;status = false;
}else{temp->val = newVal;
if (*head == 0){temp->next = 0;*head = temp;
}
else{temp->next = *head;*head = temp;
}}return (status);
}
int main(void){ListNodeClass *head = 0;printList(head);insertAtHead(&head, 5);insertAtHead(&head, 8);insertAtHead(&head, 17);printList(head);return (0);
}
List is Empty!17 8 5
Reference to pointer example
// Reference to pointer example#include <iostream> using namespace std;
void increment(int*& i) { i++; }
int main() { int* i = 0; cout << "i = " << i << endl; increment(i); cout << "i = " << i << endl;
}
04
COP 3330 Object Oriented Programming in C++ Lecture Slides 76/134 (c) pk
3
Deleting From Front Of Listbool deleteFromFront(
ListNodeClass **head){bool status = true;ListNodeClass *temp;
if (*head == 0){cout << "Can't delete from list"
<< endl;status = false;
}else{temp = *head;*head = temp->next;//Free the memory we dynamically //allocated in insert functiondelete temp;
}return (status);
}
int main(void){ListNodeClass *head = 0;printList(head);insertAtHead(&head, 5);insertAtHead(&head, 8);insertAtHead(&head, 17);printList(head);deleteFromFront(&head);printList(head);deleteFromFront(&head);deleteFromFront(&head);printList(head);deleteFromFront(&head);return (0);
}
List is Empty!17 8 58 5List is Empty!Cannot delete from list!
Searching A Listbool searchList(ListNodeClass *head, int val){bool found = false;ListNodeClass *temp = head;
while (temp != 0 && !found){if (temp->val == val){
found = true;}else{
temp = temp->next;}
}return (found);
}
The Stack Linked StructureA stack is another data structure
Used to organize data in a certain wayThink of a stack as a stack of cafeteria trays
Take a tray off the top of the stackPut washed trays on the top of the stack
Bottom tray is not accessed unless it is the only tray in the stack.Since only the top of a stack can be accessed, there needs to be only one insert function and one delete function
Inserting to a stack is usually called "push"Deleting from a stack is usually called "pop"
takeTray() putTray()
The Queue Linked StructureA queue is another data structure.Think of a queue as a line of people at a store
Get into the line at the back (insert)Person at front is served next (delete)
Can only insert at one end of the queue.Inserting to a queue is usually called "enqueue()" "Get In Line" in above diagram
Can only remove at the other end of the queueRemoving from a queue is usually called "dequeue()""Serve Customer" in above diagram
Server
Get In Line Serve Customer
Another Queue Pic: FIFO
First In First out.
© Mark Nelson
Priority Queue Pic: FIFO
Highest priority goes out first.The STL has three container adaptor types: stack, queue, and priority_queue.
© Mark Nelson
COP 3330 Object Oriented Programming in C++ Lecture Slides 77/134 (c) pk
4
The Priority Queue Linked Structure
A priority queue works slightly differently than a "normal" queueElements in a priority queue are sorted based on a priority
Queue order is not dependent on the order in which elements were inserted, as it was for a normal queueAs elements are inserted, they are sorted such that the element with the highest priority is at the beginning of the priority queueWhen an element is removed from the priority queue, the first element (highest priority) is taken, regardless of when itwas insertedElements of the same priority are maintained in the order which they were inserted
Using a priority queue in which all elements have the same priority is equivalent to using a "normal" queue
The Doubly-Linked List StructureThe linked list examples we've seen so far have only one pointerOften, it may be advantageous to have a node contain multiple pointers
2 4 6 8"head" "tail"
class DoublyLinkedListNodeClass{
DoublyLinkedListNodeClass *prev;int val;DoublyLinkedListNodeClass *next;
};
DoublyLinkedListNodeClass *head;DoublyLinkedListNodeClass *tail;
STL list<>
A list is a doubly linked list. Example
list<int> L;L.push_back(0);L.push_front(1);L.insert(++L.begin(), 2);copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));// The values that are printed are 1 2 0
http://www.sgi.com/tech/stl/List.html
Note that singly linked lists, which only support forward traversal, are also sometimes useful. If you do not need backward traversal, then slist may be more efficient than list.
Container Adaptors
Container adaptors take sequence containers as their type arguments, for example:
stack < vector < int > > a;
Stack (Last In First Out)
Use with vector (best/default), deque, or list (bad choice)
Basic interface:bool empty(); size_type size(); value_type& top(); const value_type& top(); void push(const value_type&); void pop();
Stack
Container Function Stack Adapter Function
back() top()push_back() push()pop_back() pop()empty() empty()size() size()
To support this functionality stack expects the underlying container to support push_back(), pop_back(), empty() or size() and back()
#include <stack> Provides: stack<T, Sequence>
COP 3330 Object Oriented Programming in C++ Lecture Slides 78/134 (c) pk
5
Stack Example.// C++ STL Headers#include <iostream>#include <vector>#include <stack>
int main( int argc, char *argv[] ){
stack<const char *, vector<const char *> > s;
// Push on stack in reverse orders.push("order");s.push("correct"); // Oh no it isn't !s.push("the");s.push("in");s.push("is");s.push("This");
// Pop off stack which reverses the push() orderwhile ( !s.empty() ) {cout << s.top() <<" "; s.pop(); /// Oh yes it is !
}cout << endl;
return( EXIT_SUCCESS );} ©Phil Ottewell's STL Tutorial
Simpler Stack exampleint main() {
stack<int> S;S.push(8);S.push(7);S.push(4);assert(S.size() == 3);
assert(S.top() == 4);S.pop();
assert(S.top() == 7);S.pop();
assert(S.top() == 8);S.pop();
assert(S.empty());}
http://www.sgi.com/tech/stl/stack.html
Queue
Use with deque (default), or list. (Vector works, but its extremely inefficient)Basic interface:
bool empty(); size_type size(); value_type& front(); const value_type& front(); value_type& back(); const value_type& back(); void push(const value_type&); void pop();
#include <queue> #include <vector> #include <list> #include <iostream>
int main( ) { using namespace std;
// Declares queue with default deque base container queue <char> q1; // Explicitly declares a queue with deque base container queue <char, deque<char> > q2;
// These lines don't cause an error, even though they // declares a queue with a vector base container queue <int, vector<int> > q3; q3.push( 10 );
// but the following would cause an error because vector has // no pop_front member function // q3.pop( ); // Declares a queue with list base container queue <int, list<int> > q4;
// The second member function copies elements from a container list<int> li1; li1.push_back( 1 ); li1.push_back( 2 ); queue <int, list<int> > q5( li1 ); cout << "The element at the front of queue q5 is " << q5.front( ) << "." << endl; cout << "The element at the back of queue q5 is " << q5.back( ) << "." << endl; }
int main() {priority_queue<int> Q;Q.push(1);Q.push(4);Q.push(2);Q.push(8);Q.push(5);Q.push(7);
assert(Q.size() == 6);
assert(Q.top() == 8);Q.pop();
assert(Q.top() == 7);Q.pop();
assert(Q.top() == 5);Q.pop();
assert(Q.top() == 4);Q.pop();
assert(Q.top() == 2);Q.pop();
assert(Q.top() == 1);Q.pop();
assert(Q.empty());}
Graphs
An introduction
COP 3330 Object Oriented Programming in C++ Lecture Slides 79/134 (c) pk
6
Graphs
A graph G = (V,E) is composed of:V: set of verticesE ⊂ V × V: set of edges connecting the vertices
An edge e = (u,v) is a __ pair of vertices
Directed graphs (ordered pairs)Undirected graphs (unordered pairs)
Directed graph
Directed Graph Undirected GRAPH
Undirected Graph Some More Graph Applications
transportation
Graphstreet intersections
Nodes Edgeshighways
communication computers fiber optic cables
World Wide Web web pages hyperlinks
social people relationships
food web species predator-prey
software systems functions function calls
scheduling tasks precedence constraints
circuits gates wires
COP 3330 Object Oriented Programming in C++ Lecture Slides 80/134 (c) pk
7
World Wide WebWeb graph.
Node: web page.Edge: hyperlink from one page to another.
cnn.com
cnnsi.comnovell.comnetscape.com timewarner.com
hbo.com
sorpranos.com
9-11 Terrorist NetworkSocial network graph.
Node: people.Edge: relationship between two people.
Reference: Valdis Krebs, http://www.firstmonday.org/issues/issue7_4/krebs
Ecological Food Web
Food web graph.Node = species. Edge = from prey to predator.
Reference: http://www.twingroves.district96.k12.il.us/Wetlands/Salamander/SalGraphics/salfoodweb.giff
Terminology
a is adjacent to b iff (a,b) ∈ Ε.degree(a) = number of adjacent vertices (Self loop counted twice)Self Loop: (a,a)
Parallel edges: E = { ...(a,b), (a,b)...}
a
a b
Terminology
A Simple Graph is a graph with no self loops or parallel edges.Incidence: v is incident to e if v is an end vertex of e.
ve
Question
Max Degree node? Min Degree Node? Isolated Nodes? Total sum of degrees over all vertices? Number of edges?
COP 3330 Object Oriented Programming in C++ Lecture Slides 81/134 (c) pk
8
QUESTION
How many edges are there in a graph with 100 vertices each of degree 4?
Connected graph
Undirected Graphs: If there is at least one path between every pair of vertices. (otherwise disconnected)
complete graph
Every pair of graph vertices is connected by an edge.
n(n-1)/2 edges
Trees
An undirected graph is a tree if it is connected and does not contain a cycle.
Theorem. Let G be an undirected graph on n nodes. Any two of the following statements imply the third.
G is connected.G does not contain a cycle.G has n-1 edges.
representation
Two waysAdjacency List
• ( as a linked list for each node in the graph to represent the edges)
Adjacency Matrix• (as a boolean matrix)
Representing Graphs11
22
3344
1122
33
44
1, 42
1, 43
1, 2, 34
2, 3, 41
Adjacent VerticesVertex
12
3
1, 2, 34
31
Terminal Vertices
Initial Vertex
COP 3330 Object Oriented Programming in C++ Lecture Slides 82/134 (c) pk
9
adjacency list adjacency matrix
Another example AL Vs AM
AL : Total space = 4|V| + 8|E| bytes (For undirected graphs its 4|V| + 16|E| bytes)AM : |V| * |V| / 8
Question: What is better for very sparse graphs? (Few number of edges)
AL Vs AM
Question: How much time does it take to find out if (vi,vj) belongs to E?
AM ?AL ?
Stable Marriage
Our next problem
COP 3330 Object Oriented Programming in C++ Lecture Slides 83/134 (c) pk
10
The problem
There are n men and n womenEach man has a preference list, so does the woman.These lists have no ties.
Devise a system by which each of the n men and n women can end up getting married.
Other Similar problems
Given a set of colleges and students pair them. (Internship – Company assignments)Given airlines and pilots, pair them.Given two images, pair the points belonging to the same point in 3D to extract depth from the two images.Dorm room assignments.Hospital residency assignments**.Your first programming assignment…
Stereo Matching
Fact: If one knows the distance between the camerasAnd the matching, its almost trivial to recover depth..
Example Preference Lists
ZYX
Man
ABA1st
BAB
2nd
CCC
3rd
CBA
Woman
XXY
1st
YYX
2nd
ZZZ
3rd
What goes wrong?
Unstable pairs: (X,C) and (B,Y)They prefer each other to current pairs.
Stable Matching
ZYX
Man
ABA1st
BAB
2nd
CCC
3rd
CBA
Woman
XXY
1st
YYX
2nd
ZZZ
3rd
No Pairs creating instability.
Another Stable Matching
ZYX
Man
ABA1st
BAB
2nd
CCC
3rd
CBA
Woman
XXY
1st
YYX
2nd
ZZZ
3rd
COP 3330 Object Oriented Programming in C++ Lecture Slides 84/134 (c) pk
11
Stability is Primary.
Any reasonable list of criteria must contain the stability criterion.
A pairing is doomed if it contains a shaky couple.
Main Idea
Idea: Allow the pairs to keep Idea: Allow the pairs to keep breaking up and reforming until breaking up and reforming until they become stablethey become stable
Can you argue that the couples will not continue breaking up and reforming forever?
Men Propose (Women dispose)
Gale-Shapley Algorithm (men propose)
Initialize each person to be free.while (some man m is free and hasn't proposed to every woman)
w = first woman on m's list to whom m has not yet proposedif (w is free)
assign m and w to be engagedelse if (w prefers m to her fiancé m')
assign m and w to be engaged, and m' to be freeelsew rejects m
COP 3330 Object Oriented Programming in C++ Lecture Slides 85/134 (c) pk
1
OperatorOverloading
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Operator overloading
C++ allows overloading of most of the standard operators. We areallowed to define standard operators for new types.
The name of an operator, as a function, is “operator” followed by the operator itself.
The operator in “a - b” is named “operator-”.
Suppose we have a class MyNum, a new numerical type.The syntax for defining operators is ReturnType operator@(argument list…)For example:
MyNum operator-(const MyNum & a, const MyNum &b);
Exampleclass MyNum {public:
...};
© C++ FAQ
// Without operator overloading:MyNum add(const MyNum& x, const MyNum& y);MyNum mul(const MyNum& x, const MyNum& y);
MyNum f(const MyNum& a, const MyNum& b, const MyNum& c){
return add(add(mul(a,b), mul(b,c)), mul(c,a)); // Yuk...}
Exampleclass MyNum {public:
...};
© C++ FAQ
// With operator overloading:MyNum operator+ (const MyNum& x, const MyNum& y);MyNum operator* (const MyNum& x, const MyNum& y);
MyNum f(const MyNum& a, const MyNum& b, const MyNum& c){
return a*b + b*c + c*a;}
More examples?
Here are a few of the many examples of operator overloading:
myString + yourString might concatenate two std::string objects myDate++ might increment a Date object a * b might multiply two Number objects a[i] might access an element of an Array object x = *p might dereference a "smart pointer" that "points" to a disk record — it could seek to the location on disk where p "points" and return the appropriate record into x
Operator Overloading
Operator overloading makes life easier for the users of a class, not for the developer of the class! Supports more natural usage.Uniformity with built in types.
COP 3330 Object Oriented Programming in C++ Lecture Slides 86/134 (c) pk
2
Operator Overloading: Another example
class Array {public:int& elem(unsigned i)
{ if (i > 99) error(); return data[i]; }private:int data[100];
};
int main(){Array a;a.elem(10) = 42;a.elem(12) += a.elem(13);...
}
class Array {public:int& operator[] (unsigned i)
{ if (i > 99) error(); return data[i]; }private:int data[100];
};
int main(){Array a;a[10] = 42;a[12] += a[13];...
}
Precedence of Operators
Ival = jval = kval = lvalRight associative(Ival = (jval = (kval = lval)))
Ival * jval / kval * lvalLeft associative(((Ival * jval) / kval) * lval)
Operator Precedence in C++
:: -> global / class / namespace scopes. ->[] subscript() ParenthesesUnary operatorsMultiplicative operatorsAdditive operatorsRelational orderingRelational equalityLogical andLogical orAssignment
Operator precedence
x == y + z;Precedence and associativity are fixed.We cannot create new operators. Nor can we change the precedence, associativity (grouping), or number of parameters.
Overloading operators
The meaning of an operator for the built in types may not be changed.
int operator+(int , int) // not allowedOperators that can not be overloaded
:: , .*, . , ?:
Operator Overloading
Can I overload operator== so it lets me compare two char[] using a string comparison?No: at least one operand of any overloaded operator must be of some user-defined type (most of the time that means a class). And you shouldn’t be using char[] anyways.
COP 3330 Object Oriented Programming in C++ Lecture Slides 87/134 (c) pk
3
Operator Overloading
Which ones should you override?The ones your user wants you to. Do not confuse your users.
Use common sense. If your overloaded operator makes life easier and safer for your users, do it; otherwise don't
Class member Vs non-memberOperators can be global or member. As a member function, the first operand
becomes its object, that is, “*this”.Substraction operator as a friend/global :
MyNum operator-(const MyNum & a, const MyNum & b);
As a member of class MyNum:
class MyNum {public:
MyNum operator-(const MyNum & b) const;…
};
MyNum MyNum::operator-(const MyNum & b) const{ // Continue as usual
Member Vs Non-Member
If MyNum::operator- defined as member function
Num1 – Num2 Num1.operator-(Num2)
As a non-member functionNum1 – Num2 operator-(Num1,Num2)
Non-Member
When operators are defined as nonmember functions, they often must be made friends.
class Sales_item {friend bool operator==(const Sales_item&, const Sales_item&);friend std::istream& operator>>(std::istream&, Sales_item&);friend std::ostream& operator<<(std::ostream&, const Sales_item&);
// other members as before…}ostream& operator<<(ostream& out, const Sales_item& s){
out << s.isbn << "\t" << s.units_sold << "\t"<< s.revenue << "\t" << s.avg_price();
return out;}
Member Vs Non-Member
‘ = ‘, ‘ [] ‘ , ‘ () ‘, ‘ -> ‘ must be defined as members ( else -> compile time error)Like assignment, compound-assignment operators ordinarily ought to be members. (but not required)
Member Vs Non-Member
Operators that change the state of the object such as increment, decrement and dereference -- usually should be member functions.Symmetric operators like arithmetic, equality, relational, and bitwise operators, are best left as non-members.
COP 3330 Object Oriented Programming in C++ Lecture Slides 88/134 (c) pk
4
Guideline:
Not a good idea to overload “,” , “&” , “ && “ , “||”These operators have built in meanings that become inaccessible if we define our own.
An operation to test whether the object is empty could be represented by “operator!” (or in a good state…)
Guideline
A class that has “+”, “=“The provide “+=“
Classes that will be used as the key type of an associative container should define “<“
“An Associative Container is a variable-sized Container that supports efficient retrieval of elements (values) based on keys. It supports insertion and removal of elements, but differs from a Sequence in that it does not provide a mechanism for inserting an element at a specific position. [1] “
Associative Containers:set , multiset , hash_set , hash_multiset , map , multimap , hash_map , hash_multimap
vector ,deque ,list ,slist
Types in containers
Define “==“ and “<“ for types that will be stored in even sequential containers.Many algorithms (e.g. find()) assume that these operators exist
Find() examplelist<MyNum> nums;list<MyNum>::iterator nums_iter;
nums.push_back (“3”);nums.push_back (“7”);nums.push_front (“10”);
nums_iter = find(nums.begin(), nums.end(), “3”); // Search the list.if (nums_iter != nums.end()){
cout << "Number " << (*nums_iter) << " found." << endl; // 3}else{
cout << "Number not found." << endl;}
// If we found the element, erase it from the list.if (nums_iter != nums.end()) nums.erase(nums_iter);// List now contains: 10 7
Equality and relational operators
If you define ‘==‘ then also define ‘!=‘If you define ‘<‘ then also define ‘<=, >=, >’
Output Operator
To be consistent with the IO library, the syntax of output operator is:
ostream&operator<<(ostream& out, const Your_Class_Type& s){
// any special logic to prepare object
// actual output of membersout << // …
// return ostream objectreturn out;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 89/134 (c) pk
5
Output Operators
Generally, output operators print the contents of the object with minimal formatting. They should not print a newline.
IO operators: Always Non-Member
// if operator<< is a member of Sales_itemSales_item item; item << cout;
The usage is the opposite of normal way we use output operators.
Input operator overloading
Must deal with end of file/errors.
When designing an input operator, decide what to do about error handling.
istream&operator>>(istream& in, Sales_item& s){
double price;in >> s.isbn >> s.units_sold >> price;// check that the inputs succeededif (in)
s.revenue = s.units_sold * price;else
s = Sales_item(); // input failed: reset object to default statereturn in;
}
Arithmetic operators
Sales_item& Sales_item::operator+=(const Sales_item& rhs){
units_sold += rhs.units_sold;revenue += rhs.revenue;return *this;
}
// assumes that both objects refer to the same isbnSales_itemoperator+(const Sales_item& lhs, const Sales_item& rhs){
Sales_item ret(lhs); // copy lhs into a local object that we'll returnret += rhs; // add in the contents of rhsreturn ret; // return ret by value
}
Operator==
inline booloperator==(const Sales_item &lhs, const Sales_item &rhs){
return lhs.units_sold == rhs.units_sold &&lhs.revenue == rhs.revenue &&lhs.same_isbn(rhs);
}
== means objects contain same data.Also define !=Classes which define == are easier to use with STL. (e.g. find())
Operator< and Sorting//// sort.cpp//
#include <vector>#include <algorithm>#include <functional>#include <iostream>
struct associate{int num;char chr;
associate(int n, char c) : num(n), chr(c){};associate() : num(0), chr(' '){};
};
COP 3330 Object Oriented Programming in C++ Lecture Slides 90/134 (c) pk
6
Operator< and sorting
bool operator<(const associate &x, const associate &y){return x.num < y.num;
}
ostream& operator<<(ostream &s, const associate &x){return s << "<" << x.num << ";" << x.chr << ">";
}
Operator< and Sortingint main ()
{vector<associate>::iterator i, j, k;
associate arr[20] ={associate(-4, ' '), associate(16, ' '),associate(17, ' '), associate(-3, 's'),associate(14, ' '), associate(-6, ' '),associate(-1, ' '), associate(-3, 't'),associate(23, ' '), associate(-3, 'a'),associate(-2, ' '), associate(-7, ' '),associate(-3, 'b'), associate(-8, ' '),associate(11, ' '), associate(-3, 'l'),associate(15, ' '), associate(-5, ' '),associate(-3, 'e'), associate(15, ' ')};
// Set up vectorsvector<associate> v(arr, arr+20), v1((size_t)20),
v2((size_t)20);
// Copy original vector to vectors #1 and #2copy(v.begin(), v.end(), v1.begin());copy(v.begin(), v.end(), v2.begin());
// Sort vector #1sort(v1.begin(), v1.end());
// Stable sort vector #2stable_sort(v2.begin(), v2.end());
// Display the resultscout << "Original sort stable_sort" << endl;for(i = v.begin(), j = v1.begin(), k = v2.begin();
i != v.end(); i++, j++, k++)cout << *i << " " << *j << " " << *k << endl;
return 0;}
Output :Original sort stable_sort<-4; > <-8; > <-8; ><16; > <-7; > <-7; ><17; > <-6; > <-6; ><-3;s> <-5; > <-5; ><14; > <-4; > <-4; ><-6; > <-3;e> <-3;s><-1; > <-3;s> <-3;t><-3;t> <-3;l> <-3;a><23; > <-3;t> <-3;b><-3;a> <-3;b> <-3;l><-2; > <-3;a> <-3;e><-7; > <-2; > <-2; ><-3;b> <-1; > <-1; ><-8; > <11; > <11; ><11; > <14; > <14; ><-3;l> <15; > <15; ><15; > <15; > <15; ><-5; > <16; > <16; ><-3;e> <17; > <17; ><15; > <23; > <23; >
Subscript operator
Must be a member-functionOrdinarily, a class that defines subscript, defines two versions.
A nonconst member returning a reference.A const member returning a const reference.
Example#include <vector>using std::vector;#include <iostream>using std::cout; using std::endl;
class Foo {public:Foo(): data(100) { for (int i = 0; i != 100; ++i) data[i] = i; }
int &operator[](const size_t);const int &operator[](const size_t) const;// other interface members
private:vector<int> data;// other member data and private utility functions
};
Example
int& Foo::operator[](const size_t index){
return data[index]; // no range checking on index}
const int& Foo::operator[](const size_t index) const{
return data[index]; // no range checking on index}
int main() {Foo f;
cout << f[50] << endl;return 0;
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 91/134 (c) pk
7
Increment and Decrement operators
// increment and decrement
CheckedPtr operator++(int); // postfix operatorsCheckedPtr operator--(int);
CheckedPtr& operator++(); // prefix operatorsCheckedPtr& operator--();
Increment and Decrement operator
// postfix: increment/decrement object but return unchanged valueCheckedPtr CheckedPtr::operator++(int){
// no check needed here, the call to prefix increment will do the checkCheckedPtr ret(*this); // save current value++*this; // advance one element, checking the incrementreturn ret; // return saved state
}
// prefix: return reference to incremented/decremented objectCheckedPtr& CheckedPtr::operator++(){
if (curr == end)throw out_of_range
("increment past the end of CheckedPtr");
++curr; // advance current statereturn *this;
}
++ / --
Advice: Make them member functions.For consistency,
Prefix operations should return a reference to the incremented/decremented objectPostfix operations should return the “old” value (and not the reference)
Calling prefix/postfix operators explicitlyMytype.operator++(0); // postfixMytype.operator++(); // prefix
Call operator and Function objects
#include <iostream>using std::cout; using std::endl;
struct absInt {int operator()(int val) {
return val < 0 ? -val : val;}
};
int main() {int i = -42;absInt absObj; // object that defines function call operatorunsigned int ui = absObj(i); // calls absInt::operator(int)cout << i << " " << ui << endl;return 0;
}
Function call operator
Must be a member functionCan be overloaded for different parameters.Objects that have call operator overloaded are often referred to as “Function Objects”
COP 3330 Object Oriented Programming in C++ Lecture Slides 92/134 (c) pk
8
Function Objects
A Function object, often called a functoror functionoid, is a computer programmingconstruct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. An advantage of function objects in C++ is performance because unlike a function pointer, a function object can be inlined.
Template Function Objects
class GenericNegate{public: template <class T> T operator() (T t) const {return -t;}
};
int main(){GenericNegate negate;__int64 val = 10000000000i64;cout<< negate(5.3333); // doublecout<< negate(val); // __int64
}
Using count_if
// determine whether a length of a given word is 6 or more
bool GT6(const string &s){return s.size() >= 6;
}
vector<string>::size_type wc =count_if(words.begin(),
words.end(), GT6);
Using FOs with STL
class GT_cls {public:
GT_cls(size_t val =0) : bound(bal) {}bool operator() (const string &s){
return s.size() >= bound; }private:
std::string::size_type bound;}
cout << count_if ( words.begin() , words.end(), GT_cls(6)) << “ words 6 characters or longer” << endl;
for(size_t I = 0; I != 11; ++I){cout << count_if ( words.begin() , words.end(), GT_cls(i))
<< “ words “ << I << “ characters or longer” << endl;}
Using FOs with STL
struct adder {double sum;adder() : sum(0) {};void operator()(double x) { sum += x; }
};
vector<double> V;...adder result = for_each(V.begin(), V.end(), adder()); cout << "The sum is " << result.sum << endl;
Using FOs with STL
vector<int> V(100); generate(V.begin(), V.end(), rand);
COP 3330 Object Oriented Programming in C++ Lecture Slides 93/134 (c) pk
9
A slight deviation
// print.hpp#include <iostream>
template <class T>inline void PRINT_ELEMENTS(
const T& collection, const char * optcstr = “” ) {
typename T::const_iterator pos;std::cout << optcstr;for ( pos = collection.begin(); pos != collection.end(); ++pos)
std::cout << *pos << ‘ ‘ ;std::cout << std::endl;
}
Usage: PRINT_ELEMENTS(myvec, “initialized to”);
How do we do the same thing using function objects?
STL FOs
#include <functional>Types of function objects.
Arithmetic FOs: • plus<Type>, minus<type>, multiplies<type>,
divides<type>, modulus<type>, negate<type>Relational FOs:
• equal_to<Type>, not_equal_to<type>, greater<type>, greater_equal<type>, less<type>, less_equal<type>
Logical FOs:• logical_and<type>, logical_or<type>,
logical_not<type>
STL FOs
Another classificationUnary FOs:
• negate<type> , logical_not<type>Binary FOs:
• The rest.
Using library FOs with Algorithms
sort(svec.begin(), svec.end(), greater<string>());
Sorts the container in ascending order.The third argument is used to pass a predicate function to use to compare elements.
Function Adaptors and FOs
FAs specialize and extend FOs.FA categories
Binders: Converts a binary FO to a unary FO by binding one of the operands to a given valueNegators: Reverses the truth value of a predicate function.
Function Adaptors (FAs)
Binder adaptors: bind1st, bind2ndbind1st binds the given value to the first argument of the binary function object. (bind2nd binds to the 2nd)count_if( vec.begin(), vec.end(), bind2nd( less_equal<int>(), 10));
COP 3330 Object Oriented Programming in C++ Lecture Slides 94/134 (c) pk
10
Function Adaptors
Negators: not1 : Reverses the truth value of a unary predicate.not2 : Reverses the truth value of a binary predicate.
Example:count_if( vec.begin(), vec.end(), not1(bind2nd( less_equal<int>(), 10)));
Example (FAs n FOs)
#include <functional>using std::plus; using std::negate;
#include <iostream>using std::cout; using std::endl;
#include <vector>#include <algorithm>using std::count_if; using std::bind2nd; using std::not1; using std::ptr_fun;using std::less_equal; using std::vector;
#include <iostream>using std::cin;
#include <string>using std::string;
bool size_compare(string s, string::size_type sz){
return s.size() >= sz;}
int main() {
cout << plus<int>()(3,4) << endl; // prints 7
plus<int> intAdd; // function object that can add two int valuesnegate<int> intNegate; // function object that can negate an int value
// uses intAdd::operator(int, int) to add 10 and 20int sum = intAdd(10, 20); // sum = 30
cout << sum << endl;
// uses intNegate::operator(int) to generate -10 as second parameter// to intAdd::operator(int, int)sum = intAdd(10, intNegate(10)); // sum = 0
cout << sum << endl;
int arry[] = {0,1,2,3,4,5,16,17,18,19};
vector<int> vec(arry, arry + 10);
cout <<count_if(vec.begin(), vec.end(),
bind2nd(less_equal<int>(), 10));cout << endl;
cout <<count_if(vec.begin(), vec.end(),
not1(bind2nd(less_equal<int>(), 10)));cout << endl;
return 0;}
Predicate functions
Returns bool. Should be a pure function: Only depend on its input parameters.
F(x,y) should only depend on x,y.A predicate class is a FO whose operator() is a predicate.
Example : less_equal<int> ()
Make FOs adaptable.
list<Widget *> widgetPtrs;class isOfInterest {public:
bool operator()( const Widget * pw) const;}
isOfInterest sInteresting;
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(), widgetPtrs.end(), isInteresting);
If ( foundit != widgetPtrs.end() ) { // found what I was looking for.
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 95/134 (c) pk
11
Make FOs adaptable.
list<Widget *> widgetPtrs;class isOfInterest {public:
bool operator()( const Widget * pw) const;}
isOfInterest sInteresting;
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(), widgetPtrs.end(), not1(isInteresting)); // ERROR
If ( foundit != widgetPtrs.end() ) { // found what I was looking for.
}
Make FOs adaptable.
list<Widget *> widgetPtrs;class isOfInterest : public unary_predicate<Widget *,bool> {public:
bool operator()( const Widget * pw) const;}
isOfInterest sInteresting;
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(), widgetPtrs.end(), not1(isInteresting));
If ( foundit != widgetPtrs.end() ) { // found what I was looking for.
}
Make FOs adaptable.
list<Widget *> widgetPtrs;class isActuallyBetter :
public binary_predicate<Widget *, Widget *, bool> {public:
bool operator()(const Widget * pw1, const Widget * pw2) const;}
isActuallyBetter isBetter;
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(), widgetPtrs.end(), bind2nd(isBetter(), mywidget));
If ( foundit != widgetPtrs.end() ) { // found what I was looking for.
}
Conversion Operators
In addition to defining conversions “to”a class type (using constructors), we can also define conversions “from” a class type.Why might we need conversion operators?
Our own SmallInt ?
Conversion Operators
Syntax:operator type();
Always a member functionclass Mystring{public:Mystring();//convert Mystring to a C-stringoperator const char * () { return s; } //...
};
int n = strcmp(mystr, “C-String"); //OK, automatic conversion of str// to const char *
Usually should be const
Do not use conversion operators (unless necessary)
class Rational {Public:
…operator double() const;
};
Rational r(1,2);double d = 0.5 *r;
cout << r << “\t” << d << endl
class Rational {Public:
…operator asDouble() const;
};
Rational r(1,2);double d = 0.5 *r;
cout << r << “\t” << d << endl
COP 3330 Object Oriented Programming in C++ Lecture Slides 96/134 (c) pk
12
Conversion operators
template<class T>class Array {public:
Array (int lb, int hb);Array (int size);T& operator[] (int index);
…}
bool operator==(const Array<int>& lhs, const Array<int>& rhs);
Array<int> a(10);Array<int> b(10);
for (int i = 0; i < 10; ++i)if ( a == b[i] ) …
Conversion operators
template<class T>class Array {public:
Array (int lb, int hb);Array (int size);T& operator[] (int index);
…}
bool operator==(const Array<int>& lhs, const Array<int>& rhs);
Array<int> a(10);Array<int> b(10);
for (int i = 0; i < 10; ++i)if ( a == b[i] ) …
Converted to : if (a == static_cast< Array<int> > (b(i)) …!!
Function objects revisited
Design function objects for pass-by-value
Keep them small, and don’t inherit them.
Template< class InputIterator, class Function > Function for_each(InputIterator first, InputIterator last,
Function f);
Conversion operators
Only one class-type conversion is applied by the compiler. (else, compile time error)Used carefully, class-type conversions can greatly simplify code. Used too freely, they can lead to mysterious errors.
Section 13.5.1, 13.5.2 and 14.9.3+ omitted.Reading assignment: Chapter 12-14.
COP 3330 Object Oriented Programming in C++ Lecture Slides 97/134 (c) pk
1
Object Oriented Programming
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
OOP
Object 2
Object 1
Object 4
Object 3
Objects: State (fields), Behavior (member functions), Identity Class : Blue print of an object.
Data and behavior are strongly linked in OOP.Objects are responsible for their behavior. Example: Complex numbers, Rational numbers, Floating point numbers
, all understand addition.
OOP components
Data AbstractionInformation Hiding, ADTs
EncapsulationType Extensibility
Operator OverloadingInheritance
Code ReusePolymorphism
Recap: ADTs
specify the meaning of the operations independent of any implementation/definition.
Least common denominator of all possible implementations.Information Hiding: Do not expose unnecessary information.
Inheritance
Two example classesClass Employee
class Employee { public:
Employee(string theName, float PayRate); string Name() const; float PayRate() const; float compute_pay(float hoursWorked) const;
protected: string name; float payrate;
};
Inheritance
Two example classesClass Manager
class Manager { public:
Manager(string theName, float PayRate); void set_manages(int n);string Name() const; float PayRate() const; float compute_pay(float hoursWorked) const;
protected: string name; float payrate;int manages_n_employees;
};
COP 3330 Object Oriented Programming in C++ Lecture Slides 98/134 (c) pk
2
Reuse
We have done unnecessary work to create Manager, which is similar to (and really is a “is a") Employee. We can fix this using the OO concept of inheritance. We let a manager inherit from an employee.
A manager gets all the data and functionality of an employee after inheritance. We can then add any new data and methods needed for a manager and redefine any methods that differ for a manager.
Manager
class Manager : public Employee { // is a relationshippublic:
Manager(string theName, float PayRate, int n); void set_manages(int n);
protected: int manages_n_employees;
};
Methods of Manager have access to name, payrate because they were declared in Employee as "protected” .
More on Inheritance : Access privileges.
In a public inheritance:Public members are accessible to derived class.Protected members are accessible to derived class. These members are not accessible to the users of the base class.But private are not.
Inheritance
Derive a new class (subclass) from an existing class (base class).
Syntax: • class classname : access-label base-class { … }• Access-labels = { public, private, protected }
Inheritance creates a hierarchy of related classes (types) which share code and interface.
More Examples
Base Class Derived Classes Student GradStudent
UnderGradStudent Shape Circle
Triangle Rectangle Tetrahedron
Loan CarLoan HomeImprovementLoan MortgageLoan
More ExamplesPerson
Student Employee
FacultyNon-FacultyGradStudent UnderGradStudent
Tenure Teaching
“Is a” relationships.
COP 3330 Object Oriented Programming in C++ Lecture Slides 99/134 (c) pk
3
Inheritance: Subclass
Code reuse• derive GradStudent from Student
(also adds fields/methods)
Specialization: Customization• derive bounded-stack from stack
(by overriding/redefining push)
Generalization: Factoring CommonalityAvoid code-duplications (why?)
Inheritance
Derived classes contain their base classes as subobjects.
Functions in the derived may use members from the base.
string name; float payrate;int manages_n_employees;
Manager object.
There is no requirement that the compiler lay out the base and derived partsof an object contiguously.
Employee object
Inheritance
A class must be defined to be used as a base class.A derived class can be used as a base-class.Forward declarations are same for base-classes as well as derived classes.
class Manager;class Employee;class Manager: public employee; // Error
Open-Closed principle in OOP
The open/closed principle states that a class must be both open and closed.
Open: means it has the ability to be extended Closed: means it cannot be modified other than by extension.
Open-Closed Principle
Open for extensionClosed for modification
An interesting paper: http://www.craiglarman.com/articles/The%20Importance%20of%20Being%20Closed%20-%20Larman%20-%20IEEE%20Software.pdf
Open-Closed principle in OOP
The idea is that once a class has been approved for use having gone through code reviews, unit tests, and other qualifying procedures, you don't want to change the class very much, just extend it.
COP 3330 Object Oriented Programming in C++ Lecture Slides 100/134 (c) pk
4
Example : Open-Closed Pr.
DeltaBoundedQueue TestBoundedQueue
Queue TestQueue
Client (Composition)
Subclass (Inheritance)
More on Inheritance
A pointer to a derived class can always be used as a pointer to a base class when public inheritance is used. (But not vice-versa)
Private base classes are differentSTL Containers which need to contain both base/derived classes should be made of pointers to base classes.
Otherwise : Slicing problem.
Virtual Methods
A base class must indicate which of its member functions it intends its derived classes to redefine. These member functions are defined as “virtual” in the base class.
Exampleclass Base {public:
int i;virtual void print(){
cout << "i value is " << i << " inside object of type Base\n\n";
}};
class Derived: public Base {public:
virtual void print(){ cout << "i value is " << i
<< " inside object of type Derived\n\n"; }};
Base *bp;Derived d;bp = &d;bp->print(); // invokes
Dynamic Binding
Allows invocation of general methods using a base class pointer.The fact that a reference or pointer might refer to either a base or derived-class object is the key to dynamic binding.Allows easy extensibility.
Dynamic Vs Static Binding
Static Binding: The compiler uses the type of the pointer to find out which method to call. Dynamic Binding: The decision is made at runtime. (uses ‘virtual’keyword)
COP 3330 Object Oriented Programming in C++ Lecture Slides 101/134 (c) pk
5
Dynamic Vs Static Binding
Static BindingLess time and space overhead.Inlining possible
Dynamic BindingExtensibility Better code-reuse.
Dynamic Vs Static Binding
Efficiency Vs FlexibilityStatic Binding
More efficient• Less time and space overhead, can use inlining.
Dynamic BindingFlexible: Enables extension of behavior of a system easily.
Virtual Functions
Have a fixed interface.Derived implementations can change.Dispatched using object’s “dynamic type” to select the appropriate method.“Once Virtual, always virtual” rule.
Once a base-class defines a function as virtual, it remains virtual through out the inheritance hierarchy.
An example base class// Item sold at an undiscounted price// derived classes will define various discount strategiesclass Item_base {friend std::istream& operator>>(std::istream&, Item_base&);friend std::ostream& operator<<(std::ostream&, const Item_base&);public:
virtual Item_base* clone() const { return new Item_base(*this); }public:
Item_base(const std::string &book = "", double sales_price = 0.0): isbn(book), price(sales_price) { }
std::string book() const { return isbn; }
// returns total sales price for a specified number of items// derived classes will override and apply different discount algorithmsvirtual double net_price(std::size_t n) const { return n * price; }
// no work, but virtual destructor needed// if base pointer that points to a derived object is ever deletedvirtual ~Item_base() { } // Always virtual. Why? (Hint: Static Vs Dynamic Binding)
private:std::string isbn; // identifier for the item
protected:double price; // normal, undiscounted price
};
Scoping rules
In a public base class, public and protected members of the base class remain public and protected members of the derived class.
Example: class circle: public pointcircle c;//can call point::move(int,int)c.move(1,2);
Scoping Rules.
Private derivation: public base class members are private in derived class. Example: class stack: private linkedList
stack s;s.insert(1,2); cannot call
linkedList::insert(int,int)Protected derivation:
public base class members are protected in derived class.
Out of scope of this class. Do not use.
COP 3330 Object Oriented Programming in C++ Lecture Slides 102/134 (c) pk
6
“Is a” Vs “Has a”
InheritanceConsidered an “Is a” class relationshipe.g.: An HourlyEmployee “is a” EmployeeA Convertible “is a” Automobile
A class contains objects of another classas it’s member data
Considered a “Has a” class relationshipe.g.: One class “has a” object of anotherclass as it’s data
OOP Shape Example
shape
rectangle
triangle circle • • • •
Public inheritance: “Is A” relationships
Abstract Base class: Shape.class Shape {public:
Shape ( Point2d& position, Color& c) : center_(position) , color_ (c) {};virtual void rotate( double radians ) = 0;virtual bool draw(Screen &) = 0;virtual ~Shape(void) = 0;void move(Point2d& p) { _center = p; };
private:Point2d center_;Color color_;
};
C++ Shape example
class Triangle: public Shape {public:
Triangle( Point2d& p[3] );virtual void rotate ( double radians ){…}virtual bool draw(Screen &s) {…};virtual ~Triangle(void) {…};
private:Point2d vertices[3];Color color_;
};
COP 3330 Object Oriented Programming in C++ Lecture Slides 103/134 (c) pk
1
Inheritance
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
OOP components
Data AbstractionInformation Hiding, ADTs
EncapsulationType Extensibility
Operator OverloadingInheritance
Code ReusePolymorphism
“Is a” Vs “Has a”
InheritanceConsidered an “Is a” class relationshipe.g.: An HourlyEmployee “is a” EmployeeA Convertible “is a” Automobile
A class contains objects of another classas it’s member data
Considered a “Has a” class relationshipe.g.: One class “has a” object of anotherclass as it’s data
Another Example
class Car : public Vehicle {public:// ...
};
We state the above relationship in several ways:* Car is "a kind of a" Vehicle* Car is "derived from" Vehicle* Car is "a specialized" Vehicle* Car is the "subclass" of Vehicle* Vehicle is the "base class" of Car* Vehicle is the "superclass" of Car (this not as common in the C++ community)
Vehicle
Car
UML
Virtual Functions
Virtual means “overridable”Runtime system automatically invokes the proper member function.
Costs 10% to 20% extra overhead compared to calling a non-virtual function call.
Virtual Destructor rule
If a class has one virtual function, you want to have a virtual destructor.A virtual destructor causes the compiler to use dynamic binding when calling the destructor.Constructors: Can not be virtual. You should think of them as static member functions that create objects.
COP 3330 Object Oriented Programming in C++ Lecture Slides 104/134 (c) pk
2
Pure virtual.
A pure virtual member function is a member function that the base class forces derived classes to provide. A pure virtual function makes a class an abstract base class (ABC)
Can not be instantiated!An ABC can also have a pure virtual destructor.
Pure virtual member functions.
Specified by writing =0 after the function parameter list.
OOP Shape Example
shape
rectangle
triangle circle • • • •
Public inheritance: “Is A” relationships
ABC
Abstract Base class: Shape.class Shape {public:
Shape ( Point2d& position, Color& c) : center_(position) , color_ (c) {};virtual void rotate( double radians ) = 0;virtual bool draw(Screen &) = 0; // Inheritance of interface.virtual ~Shape(void) = 0; virtual void error(const string& msg); // Inheritance of implementation.int ObjectID() const; // Do not redefine.void move(Point2d& p) { _center = p; };
private:Point2d center_;Color color_;
};
C++ Shape example
class Triangle: public Shape {public:
Triangle( Point2d& p[3] );virtual void rotate ( double radians ){…}virtual bool draw(Screen &s) {…};virtual ~Triangle(void) {…};// Can use the default error// Must not define / declare ObjectID
private:Point2d vertices[3];
};
Concrete derived class
Has no pure virtual functions.Simply provides the definition of all the pure virtual functions in its ABC.
COP 3330 Object Oriented Programming in C++ Lecture Slides 105/134 (c) pk
3
Typecasts
Can I convert a pointer of a derived class type to a base class type?
? Does it require a typecast?
Containers and Inheritance
Because derived objects are “sliced down” when assigned to a base object, containers and types related by inheritance do not mix well.
multiset<Item_base> basket;Item_base base;Bulk_item bulk;basket.insert(base);basket.insert(bulk); // problem! (Slicing!)
Questions
How can a class Y be a kind-of another class X as well as get the bits of X?
Is-a relationshipHow can a class Y get the bits of X without making Y a kind-of X?
Has a relationship
Inheritance
Except for friendship, inheritance is the strongest relationship that can be expressed in C++, and should be only be used when it's really necessary.
Multiple Inheritance
Multiple inheritance refers to a feature of object-oriented programming languages in which a class can inherit behaviors and features from more than one superclass. Multiple inheritance can cause some confusing situations (A Diamond!)
Java compromises. (can inherit implementation from only one parent).
Virtual inheritance is used to solve problems caused by MI.
Virtual and Multiple Inheritance
Multiple and virtual Inheritance: Beyond the scope of this class.
COP 3330 Object Oriented Programming in C++ Lecture Slides 106/134 (c) pk
4
Polymorphism
Literal meaning : “Many forms”We can use the “many forms” of derived and base classes interchangeably.The fact that static and dynamic types of references and pointers can differ is the cornerstone of how C++ supports polymorphism.
Polymorphism.
C++ supports several kinds of static (compile-time) and dynamic (run-time) polymorphism.
Static Polymorphism• Function/Operator Overloading• Class/function templates
Dynamic polymorphism• Polymorphism through inheritance/Virtual
member functions
Polymorphism : Example#include <iostream>
class Bird // the "generic" base class{public:virtual void OutputName() {std::cout << "a bird";}virtual ~Bird() {}
};
class Swan : public Bird // Swan derives from Bird{ public:void OutputName() {std::cout << "a swan";} // overrides virtual function
};
int main(){Bird* myBird = new Swan; // Declares a pointer to a generic Bird,
// and sets it pointing to a newly-created Swan.myBird->OutputName(); // This will output "a swan", not "a bird".delete myBird;return 0;
}
RTTI: Run time type identification.
C++ has the ability to determine the type of a program's object/variable at runtime.
class base {virtual ~base(){}
};
class derived : public base {public:
virtual ~derived(){}int compare (derived &ref);
};
int my_comparison_method_for_generic_sort (base &ref1, base &ref2){
derived & d = dynamic_cast<derived &>(ref1); // rtti used here// rtti enables the process to throw a bad_cast exception// if the cast is not successfulreturn d.compare (dynamic_cast<derived &>(ref2));
}
Inheritance Guidelines
Prefer minimal classes.D&C: Small classes are easier to write, get right, test, use …
Prefer composition to inheritance.Avoid inheriting from classes that were not designed to be base classes.Prefer providing abstract interfaces.
Inheritance
Differentiate between inheritance of interface and inheritance of implementation
Member function interfaces are always inherited.Purpose of pure virtual function is to have derived classes inherit a function interface only.Purpose of declaring a simple virtual function is to have derived classes inherit a function interface as well as a default implementation.Purpose of non-virtual function is to have a derived class inherit a function interface as well as a mandatory implementation.
COP 3330 Object Oriented Programming in C++ Lecture Slides 107/134 (c) pk
5
Inheritance
Never redefine an inherited non-virtual function.Never redefine an inherited default parameter value.
Virtual functions are dynamically bound but default parameter values are statically bound.
Inheritance and templates.
Consider the two design problemsA stack of objects. Each stack is homogeneous. You might have a stack of ints, strings, …Classes representing monkeys. You need several different classes representing monkeys (each breed is a little different).
Sound similar? They result in utterly different software design.
Inheritance and templates.
With both stacks and monkeys, you are dealing with variety of different types.(objects of type T, monkeys of breed T)Question you want to ask yourself:
Does the type T affect the behavior of the class?
• Nope : Use templates• Yup: You need virtual functions?
Some real interview questions.
What is an explicit constructor?What is a mutable member?Explain the ISA and Has-A class relationships. How would you implement each in a class design?What is a virtual destructor?What is the difference between a copy constructor and an overloaded assignment operator?
Your next assignment.
BigNumber
BigRationalBigInteger
BigNumberclass BigNumber {…const int bitsize = 128; // All derived numbers should work upto 128 bits. virtual void print(); // prints the value of the number to cout
public:virtual ~BigNumber();
}
Operators overloaded: << , + , * , >> (Left and right shift)
Provide other functions in your interface as needed.Operator+ and * should work for mixed type arithmetic.
COP 3330 Object Oriented Programming in C++ Lecture Slides 108/134 (c) pk
6
Your library should …
BigInteger i1(7); //default bit length = 128bitsBigRational r2(32,7); //represents 32/7BigInteger & n1 = i1;BigRational & n2 = r2;BigRational n3 = n1 * n2; // n3 should be a Rational
// whose value is 32n1 = (n1 + n3) + n1; // n1 should be an Integer
// n1 = 7 + 32 + 7 = 46cout << n3 << endl;cout << n2 << endl;cout << ((n1 + 1) >> 1) << endl; // 4 now
Deadline: Nov 20th. 11am
Next homework: BFS on Graphs. Start designing your graph data structure class in C++. You need to submit the spec sheet in the beginning of class on Nov 14th.
Graph libraries
LEDAhttp://www.mpi-sb.mpg.de/LEDA/MANUAL/graph.html
Boost Graphhttp://www.boost.org/libs/graph/doc/graph_concepts.html
COP 3330 Object Oriented Programming in C++ Lecture Slides 109/134 (c) pk
1
Profiling Tools 1
Profiling tools
Piyush Kumar for COP 3330.
Slide source : Vitaly Kroivets
Profiling Tools 2
Contents
IntroductionSoftware optimization process , optimization traps and pitfallsTests / Benchmark
Performance tools overview Optimizing compilersSystem Performance monitors
Profiling toolsGNU gprofValgrind
What does it mean to use system efficiently
Profiling Tools 3
The Problem
PC speed increased 500 times since 1981, but today’s software is more complex and still hungry for more resourcesHow to run faster on same hardware and OS architecture?
Highly optimized applications run tens times faster than poorly written ones.Using efficient algorithms and well-designed implementations leads to high performance applications
Profiling Tools 4
The Software Optimization Process
Find hotspots
Modify application
Retest using benchmark Investigate causes
Create tests/benchmark
Hotspots are areas in your code that take a long time to execute
Profiling Tools 5
Extreme Optimization Pitfalls
Large application’s performance cannot be improved before it runsBuild the application then see what machine it runs on Runs great on my computer…Debug versus release buildsPerformance requires assembly language programmingCode features first then optimize if there is time leftover
Profiling Tools 6
Key Point:
Software optimization doesn’tbegin where coding ends –
It is ongoing process that starts at design stage and
continues all the way throughdevelopment
Corollary: Premature optimization is rootof all evil.
COP 3330 Object Oriented Programming in C++ Lecture Slides 110/134 (c) pk
2
Profiling Tools 7
Tests / Benchmarks
Implement before you touch your code.
Profiling Tools 8
Attributes of good tests/benchmark
Repeatable (consistent measurements)
Remember system tasks , caching issuesuse minimum performance number?
Representative Execution of typical code path, mimic how customer uses the applicationPoor benchmarks : Using QA tests
Profiling Tools 9
Test/Benchmark attributes (cont.)
Easy to runVerifiable Measure Elapsed Time vs. other numberUse benchmark to test functionality
Algorithmic tricks to gain performance may break the application…
Profiling Tools 10
How to find performance bottlenecks
Determine how your system resources, such as memory and processor, are being utilized to identify system-level bottlenecksMeasure the execution time for each module and function in your applicationDetermine how the various modules running on your system affect the performance of each otherIdentify the most time-consuming function calls and call sequences within your applicationDetermine how your application is executing at the processor level to identify microarchitecture-level performance problems
Profiling Tools 11
Performance Tools Overview
Timing mechanismsStopwatch : UNIX time tool
Optimizing compiler (easy way)System load monitors
vmstat , iostat , perfmon.exe, Vtune Counter, topSoftware profiler
Gprof, VTune, Visual C++ Profiler, IBM QuantifyMemory debugger/profiler
Valgrind , IBM Purify, Parasoft Insure++
Profiling Tools 12
Using Optimizing Compilers
Always use compiler optimization settings to build an application for use with performance toolsUnderstanding and using all the features of an optimizing compiler is required for maximum performance with the least effort
COP 3330 Object Oriented Programming in C++ Lecture Slides 111/134 (c) pk
3
Profiling Tools 13
Optimizing Compiler : choosing optimization flags combination
Profiling Tools 14
Optimizing Compiler’s effect
Profiling Tools 15
Optimizing Compilers: Conclusions
Some processor-specific options still do not appear to be a major factor in producing fast codeMore optimizations do not guarantee faster codeDifferent algorithms are most effective with different optimizationsIdea : use statistics gathered by profiler as input for compiler/linker
Profiling Tools 16
Profilers
Profiler may show time elapsed in each function and its descendants
number of calls , call-graph (some)
Profilers use either instrumentation or sampling to identify performance issues
Profiling Tools 17
Sampling vs. Instrumentation
Yes – can see algorithm,call path is expensive
No, Limited to processes , threadsDetects algorithmic issues
Functions, sometimes statements
Assembly level instr., with src line Data granularity
Call graph , call times, critical path
Counters, processor an OS stateData collected
Automatic ins. of data collection stubs required
NoneSetup
No Yes , can detect other programs using OS resources
Detect unexpected events
Just application and instrumented DLLs
Yes, profiles all app, drivers, OS functionsSystem-wide profiling
High, may be 500% !Typically about 1%Overhead
InstrumentationSampling
Profiling Tools 18
Profiling Tools
GprofProf (less extensive than gprof)
Valgrind
Old, buggy and inaccurate
Is not profiler really …
man gcov/gprof/prof
COP 3330 Object Oriented Programming in C++ Lecture Slides 112/134 (c) pk
4
Profiling Tools 19
GNU gprof
Instrumenting profiler for every UNIX-like system
Profiling Tools 20
Using gprof GNU profiler
Compile and link your program with profiling enabledcc -g -c myprog.c utils.c -pg cc -o myprog myprog.o utils.o -pgExecute your program to generate a profile data file
Program will run normally (but slower) and will write the profile data into a file called gmon.out just before exitingProgram should exit using exit() function
Run gprof to analyze the profile datagprof a.out
Profiling Tools 21
Example Program
Profiling Tools 22
The flat profile shows the total amount of time your program spent executing each function. If a function was not compiled for profiling, and didn't run long enough to show up on the program counter histogram, it will be indistinguishable from a function that was never called
Understanding Flat Profile
Profiling Tools 23
Flat profile : %time
Percentage of the total executiontime your program spent in this function.
These should all add up to 100%.
Profiling Tools 24
Flat profile: Cumulative seconds
This is cumulative total number ofseconds the spent in this functions, plus the time spent in all the functions above this one
COP 3330 Object Oriented Programming in C++ Lecture Slides 113/134 (c) pk
5
Profiling Tools 25
Number of seconds accountedfor this function alone
Flat profile: Self seconds
Profiling Tools 26
Number of times was invoked
Flat profile: Calls
Profiling Tools 27
Average number of sec per call Spent in this function alone
Flat profile: Self seconds per call
Profiling Tools 28
Average number of seconds spent in this function and its descendents
per call
Flat profile: Total seconds per call
Profiling Tools 29
Call Graph : call tree of the program
Current Function:
g( )
Called by :main ( )
Descendants: doit ( )
Profiling Tools 30
Call Graph : understanding each line
Current Function:
g( )
Uniqueindex of this
function
Percentage of the `total‘time spent in this function
and its children.
Total time propagatedinto this function by its
children
total amount oftime spent inthis function
Number of times was called
COP 3330 Object Oriented Programming in C++ Lecture Slides 114/134 (c) pk
6
Profiling Tools 31
Call Graph : understanding each lineCurrent Function:
g( )
Time that was propagatedfrom the function's children
into this parent
Time that was propagated directly from the function
into this parent
Number of times this parentcalled the function `/‘
total number of times the function was called
Call Graph : parents numbers
Profiling Tools 32
Call Graph : “children” numbers
Current Function:
g( )
Amount of time that was propagated from the child's children to the function
Amount of time that was propagated directly
from the child into function
Number of times this functioncalled the child `/‘
total number of times this child was called
Profiling Tools 33
How gprof works
Instruments program to count callsWatches the program running, samples the PC every 0.01 sec
Statistical inaccuracy : fast function may take 0 or 1 samplesRun should be long enough comparing with sampling periodCombine several gmon.out files into single report
The output from gprof gives no indication of parts of your program that are limited by I/O or swapping bandwidth. This is because samples of the program counter are taken at fixed intervals of run timenumber-of-calls figures are derived by counting, not sampling. They are completely accurate and will not vary from run to run if your program is deterministic Profiling with inlining and other optimizations needs care
Profiling Tools 34
Valgrind
Multi-purpose Linux x86 profiling tool
Profiling Tools 35
Valgrind Toolkit
Memcheck is memory debuggerdetects memory-management problems
Cachegrind is a cache profilerperforms detailed simulation of the I1, D1 and L2 caches in your CPU
Massif is a heap profilerperforms detailed heap profiling by taking regular snapshots of a program's heap
Helgrind is a thread debuggerfinds data races in multithreadedprograms
Profiling Tools 36
Memcheck Features
When a program is run under Memcheck's supervision, all reads and writes of memory are checked, and calls to malloc/new/free/delete are intercepted
Memcheck can detect: Use of uninitialised memory Reading/writing memory after it has been free'dReading/writing off the end of malloc'd blocks Reading/writing inappropriate areas on the stack Memory leaks -- where pointers to malloc'd blocks are lost forever Passing of uninitialised and/or unaddressible memory to system calls Mismatched use of malloc/new/new [] vs free/delete/delete [] Overlapping src and dst pointers in memcpy() and related functions Some misuses of the POSIX pthreads API
COP 3330 Object Oriented Programming in C++ Lecture Slides 115/134 (c) pk
7
Profiling Tools 37
Memcheck Example
Using non-initialized
value
Using “free” of memory allocated
by “new”
Access of unallocated
memory
Memory leak
Profiling Tools 38
Memcheck Example (Cont.)
Compile the program with –g flag:g++ -c a.cc –g –o a.out
Execute valgrind :valgrind --tool=memcheck --leak-check=yes a.out > log
View log
Debug leaks
Executable name
Profiling Tools 39
Memcheck report
Profiling Tools 40
Memcheck report (cont.)Leaks detected:
STACK
Profiling Tools 41
Cachegrind
Detailed cache profiling can be very useful for improving the performance of the program
On a modern x86 machine, an L1 miss will cost around 10 cycles, and an L2 miss can cost as much as 200 cycles
Cachegrind performs detailed simulation of the I1, D1 and L2 caches in your CPU Can accurately pinpoint the sources of cache misses in your codeIdentifies number of cache misses, memory references and instructions executed for each line of source code, with per-function, per-module and whole-program summariesCachegrind runs programs about 20--100x slower than normal
Profiling Tools 42
How to run
Run valgrind --tool=cachegrind in front of the normal command line invocation
Example : valgrind --tool=cachegrind ls -lWhen the program finishes, Cachegrind will print summary cache statistics. It also collects line-by-line information in a file cachegrind.out.pidExecute cg_annotate to get annotated source file:
cg_annotate --7618 a.cc > a.cc.annotatedPID
Source files
COP 3330 Object Oriented Programming in C++ Lecture Slides 116/134 (c) pk
8
Profiling Tools 43
Cachegrind Summary output
I-cache reads(instructions executed) I1 cache read misses
L2-cache instructionread misses
Instruction cachesperformance
Profiling Tools 44
Cachegrind Summary outputD-cache reads(memory reads)
L2-cache dataread misses
Data cachesREAD performanceD1 cache read misses
Profiling Tools 45
Cachegrind Summary outputD-cache writes(memory writes)
D1 cache write misses
L2-cache datawrite misses
Data cachesWRITE performance
Profiling Tools 46
Cachegrind Accuracy
Valgrind's cache profiling has a number of shortcomings:
It doesn't account for kernel activity -- the effect of system calls on the cache contents is ignoredIt doesn't account for other process activity (although this is probably desirable when considering a single program) It doesn't account for virtual-to-physical address mappings; hence the entire simulation is not a true representation of what's happening in the cache
Profiling Tools 47
Massif tool
Massif is a heap profiler - it measures how much heap memory programs use. It can give information about:
Heap blocksHeap administration blocksStack sizes
Help to reduce the amount of memory the program usessmaller program interact better with caches, avoid paging
Detect leaks that aren't detected by traditional leak-checkers, such as Memcheck
That's because the memory isn't ever actually lost -a pointer remains to it - but it's not in use anymore
Profiling Tools 48
Executing Massif
Run valgrind –tool=massif progProduces following:
Summary Graph Picture Report
Summary will look like this:Total spacetime: 2,258,106 ms.BHeap: 24.0% Heap admin: 2.2% Stack (s): 73.7%
number of words allocated on
heap, via malloc(), new and
new[].
Space (in bytes) multiplied by time (in milliseconds).
COP 3330 Object Oriented Programming in C++ Lecture Slides 117/134 (c) pk
9
Profiling Tools 49
Spacetime Graphs
Profiling Tools 50
Spacetime Graph (Cont.)
Each band represents single line of source codeIt's the height of a band that's important Triangles on the x-axis show each point at which a memory census was taken
Not necessarily evenly spread; Massif only takes a census when memory is allocated or de-allocated The time on the x-axis is wall-clock time
not ideal because can get different graphs for different executions of the same program, due to random OS delays
Profiling Tools 51
Text/HTML Report example
Contains a lot of extra information about heap allocations that you don't see in the graph.
Shows places in the program where most memory was
allocated
Profiling Tools 52
Valgrind – how it works
Valgrind is compiled into a shared object, valgrind.so. The shell script valgrind sets the LD_PRELOAD environment variable to point to valgrind.so. This causes the .so to be loaded as an extra library to any subsequently executed dynamically-linked ELF binary
The dynamic linker allows each .so in the process image to have an initialization function which is run before main(). It also allows each .so to have a finalization function run after main() exits
When valgrind.so's initialization function is called by the dynamic linker, the synthetic CPU to starts up. The real CPU remains locked in valgrind.so until end of run
System call are intercepted; Signal handlers are monitored
Profiling Tools 53
Valgrind Summary
Valgrind will save hours of debugging timeValgrind can help speed up your programsValgrind runs on x86-LinuxValgrind works with programs written in any language
Valgrind is actively maintainedValgrind can be used with other tools (gdb)Valgrind is easy to use
uses dynamic binary translation, so no need to modify, recompile or re-link applications. Just prefix command line with valgrind and everything works
Valgrind is not a toyUsed by large projects : 25 millions lines of code
Valgrind is free
Profiling Tools 54
Other Tools
Tools not included in this presentation:Intel’s VtuneIBM PurifyParasoft InsureKCachegrindOprofileGCC’s and GLIBC’s debugging hooks
COP 3330 Object Oriented Programming in C++ Lecture Slides 118/134 (c) pk
10
Profiling Tools 55
Writing Fast Programs
Select right algorithm (Take COP 4531)Implement it efficiently
Detect hotspots using profiler and fix themUnderstanding of target system architecture is often required – such as cache structureUse platform-specific compiler extensions –memory pre-fetching, cache control-instruction, branch prediction, SIMD instructionsWrite multithreaded applications (“Hyper Threading Technology”)
Profiling Tools 56
CPU Architecture (Pentium 4)
Instructionfetch
Instructiondecode
Branchprediction
ExecutionUnits
retirementInstructionpool
Memory
Out-of-order
Execution !
Profiling Tools 57
Instruction Execution
Instructionpool Dispatch unit
Integer
Integer
Memory Save
Memory Load
Floating point
Floating point
Execution Units
Profiling Tools 58
Keeping CPU Busy
Processors are limited by data dependencies and speed of instructions
Keep data dependencies lowGood blend of instructions keep all execution units busy at same timeWaiting for memory with nothing else to execute is most common reason for slow applicationsGoals: ready instructions, good mix of instructions and predictable branches
Remove branches if possible Reduce randomness of branches, avoid function pointers and jump tables
Profiling Tools 59
Memory Overview (Pentium 4)
L1 cache (data only) 8 kbytesL2 Advanced Transfer Cache (data + instructions) 256 kbytes, 3 times slower than L1L3 : 4MB cache (optional)Main RAM (usually 64M … 4G) , 10 times slower than L1
Profiling Tools 60
Fixing memory problems
Use less memory to reduce compulsory cache missesIncrease cache efficiency (place items used at same time near each other)Read sooner with “prefetch”Avoid conflictsAvoid capacity issuesAdd more work for CPU (execute non-dependent instruction while waiting)
COP 3330 Object Oriented Programming in C++ Lecture Slides 119/134 (c) pk
11
Profiling Tools 61
References
SPEC website http://www.specbench.org
The Software Optimization CookbookHigh-Performance Recipes for the Intel® Architecture
by Richard Gerber GCC Optimization flags http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
Valgrind Homepage http://valgrind.kde.org
An Evolutionary Analysis of GNU C Optimizations Using Natural Selection to Investigate Software Complexities by Scott Robert LaddIntel VTune Performace Analyzer webpagehttp://www.intel.com/software/products/vtune/
Gprof man page http://www.gnu.org/software/binutils/manual/gprof-2.9.1/html_mono/gprof.html
COP 3330 Object Oriented Programming in C++ Lecture Slides 120/134 (c) pk
1
An introduction to C++ Templates
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Templates
Are C macros on Steroids Give you the power to parametrizeCompile time computationPerformance
“The art of programming programsthat read, transform, or write other programs.”
- François-René Rideau
Generic Programming
How do we implement a linked list with a general type inside?
void pointers?Using macros?Using Inheritance?
Templates
Function TemplatesClass TemplatesTemplate templates *Full Template specializationPartial template specialization
Metaprogramming
Programs that manipulate other programs or themselvesCan be executed at compile time or
runtime.Template metaprograms are
executed at compile time.
Good old CC code
Double square(double x) { return x*x; }• sqare(3.14) Computed at compile time
#define square(x) ((x)*(x))Static double sqrarg; #define SQR(a) (sqrarg=(a), sqrarg*sqrarg)
COP 3330 Object Oriented Programming in C++ Lecture Slides 121/134 (c) pk
2
Templates
Help us to write code without being tied to particular type.Question: How do you swap two
elements of any type? How do you return the square of any type?
Defining the template
Template parameter T.Syntax: template < comma separated list of parameters >For historical reasons, you can use “class” instead of typename.
template <typename T>inline T const& min (T const& a, T const& b){
return a < b ? a : b ;}
min.hpp
Using the template
#include <iostream>#include <string>#include “min.hpp”
int main(){int i = 12;std::cout << “min(7,i): “ << ::min(7,i) << std::endl;std::string s1 = “math”; std::string s2 = “cs”; std::cout << “min(s1,s2): “ << ::min(s1,s2) << std::endl;
}
inline int const& min(int const& a, int const& b){return a < b ? a : b;
}
The process of replacing templateparameters with concrete types is calledinstantiation.
A compile time error
// The following does not provide operator<std::complex<float> c1,c2;
…
min(c1,c2); // error at compile time.
Attempt to instantiate a template for a type that doesn’t support all the Operations used within it will result in a compile-time error.
Function Templates
C++template< typename T >inline T square ( T x ) { return x*x; }A specialization is instantiated if needed :
• square<double>(3.14)
Template arguments maybe deduced from the function arguments square(3.14)MyType m; … ; square(m); expands to square<MyType>(m)
Operator * must be overloaded for MyType
Function Templates
template<typename T>void swap( T& a, T& b ){
T tmp(a); // cc requireda = b; // ao required b = tmp;
}
Mytype x = 1111;Mytype y = 100101;swap(x,y); swap<Mytype>(…) is instantiated
Note reliance on T’s concepts (properties):In above, T must be copyable and assignableCompile-time enforcement (concept-checking) techniques available
COP 3330 Object Oriented Programming in C++ Lecture Slides 122/134 (c) pk
3
Argument deduction
template <typename T> // T is a template parameterinline T const& min (T const& a, T const& b){ // a and b are call parameter.
return a < b ? a : b ;}
min(4,7); // ok : T is int for both arguments.min(4,4.2); // error: First T is int, second T is double.
Solutions:1. min ( static_cast<double>(4), 4.2); // ok2. min<double>(4,4.2); // ok
Template Parameters.
You may have as many template parameters as you like.
template <typename T1, typename T2> inline T1 min (T1 const& a, T2 const& b){
return a < b ? a : b ;}
min(4,4.2); // ok : but type of first argument defines return type.// drawback : min (4,4.2) is different compared to min(4.2,4)// return is created by an implicit typecast and can not be returned as// a reference.
Template parameters.
template <typename T1, typename T2 , typename RT > inline RT min (T1 const& a, T2 const& b){
return static_cast<RT>(a < b ? a : b);}
min<int,double,double>(4,4.2); // ok: but long and tedious
template < typename RT, typename T1, typename T2 > inline RT min (T1 const& a, T2 const& b){
return static_cast<RT>(a < b ? a : b);}
min<double>(4,4.2); // ok: return type is double.
Function Template Specialization
template<>void swap<myclass>( myclass& a, myclass& b){
a = b = 0;}
Custom version of a template for a specific class
Class Templates
template<typename NumType, unsigned D> class dpoint{public:
NumType x[D]; };
A simple 3-dimensional point.dpoint<float,3> point_in_3d;point_in_3d.x[0] = 5.0;point_in_3d.x[1] = 1.0;point_in_3d.x[2] = 2.0;
Note the explicit instantiation
Class templates.
template<typename NumType, unsigned D> class dpoint { public:
inline virtual void normalize (void); }
template<typename NumType, unsigned D> void dpoint<NumType,D>::normalize (void){
NumType len = sqrt(sqr_length()); if (len > 0.00001) for(unsigned i = 0; i < D; ++i){ x[i] /= len; }
}
Implementing a member function.
COP 3330 Object Oriented Programming in C++ Lecture Slides 123/134 (c) pk
4
Friend templatestemplate<typename NumType, unsigned D> class dpoint { public:
template<typename NT, unsigned __DIM> friend bool operator!= (const dpoint<NT,__DIM>& p,
const dpoint<NT,__DIM>& q); }
template<typename NT, unsigned __DIM> bool operator!= (const dpoint<NT,__DIM>& p,
const dpoint<NT,__DIM>& q){ //…
}
Member templates.template <typename T>class Stack {
private:std::deque<T> elems; // elements
public:void push(const T&); // store new top elementvoid pop(); // remove top elementT top() const; // return top elementbool empty() const { // return whether the stack is empty
return elems.empty();}
// assign stack of elements of type T2template <typename T2>Stack<T>& operator= (Stack<T2> const&);
};
Member Templates
template <typename T>template <typename T2>
Stack<T>& Stack<T>::operator= (Stack<T2> const& op2){
if ((void*)this == (void*)&op2) { // assignment to itself?return *this;
}
Stack<T2> tmp(op2); // create a copy of the assigned stack
elems.clear(); // remove existing elementswhile (!tmp.empty()) { // copy all elements
elems.push_front(tmp.top());tmp.pop();
}return *this;
}
Parameterized container.template <typename T, typename CONT = std::deque<T> >class Stack {
private:CONT elems; // elements
public:void push(T const&); // push elementvoid pop(); // pop elementT top() const; // return top elementbool empty() const { // return whether the stack is empty
return elems.empty();}
// assign stack of elements of type T2template <typename T2, typename CONT2>Stack<T,CONT>& operator= (Stack<T2,CONT2> const&);
};
Member template again.template <typename T, typename CONT>template <typename T2, typename CONT2>
Stack<T,CONT>&Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2){
if ((void*)this == (void*)&op2) { // assignment to itself?return *this;
}
Stack<T2,CONT2> tmp(op2); // create a copy of the assigned stack
elems.clear(); // remove existing elementswhile (!tmp.empty()) { // copy all elements
elems.push_front(tmp.top());tmp.pop();
}return *this;
}
Spot the problem
#include <string>
// note: reference parameterstemplate <typename T>inline T const& max (T const& a, T const& b){
return a < b ? b : a;}
int main(){
std::string s;
::max("apple","peach"); // OK::max("apple","tomato"); // ERROR::max("apple",s); // ERROR
}
COP 3330 Object Oriented Programming in C++ Lecture Slides 124/134 (c) pk
5
Class Templates: Unlike function templates
Class template arguments can’t be deduced in the same way, so usually written explicitly:
dpoint <double, 2> c; // 2d pointClass template parameters may have default values:
template< class T, class U = int >class MyCls { … };
Class templates may be partially specialized:template< class U >class MyCls< bool, U > { … };
Using Specializations
First declare (and/or define) the general case:template< class T >class C { /* handle most types this way */ };
Then provide either or both kinds of special cases as desired:
template< class T > class C< T * > { /* handle pointers specially */ };template<> // note: fully specializedclass C< int * > { /* treat int pointers thusly */ };
Compiler will select the most specialized applicable class template
Template TemplateParameters
A class template can be a template argumentExample:
template< template<typename ELEM> class Bag
>class C { // …
Bag< float > b;};
Or even:template< class E,
template<typename ELEM> class Bag >class C { // …
Bag< E > b;};
More Templates
template<unsigned u>class MyClass {
enum { X = u };};
Cout << MyClass<2>::X << endl;
Template MetaprogramsFactorials at compile time
template<int N> class Factorial { public:
enum { value = N * Factorial<N-1>::value };};
template<>class Factorial<1> {
public: enum { value = 1 };
};
int w = Factorial<10>::value;
Template Metaprograms
Metaprogramming using C++ can be used to implement a turning machine. (since it can be used to do conditional and loop constructs).
COP 3330 Object Oriented Programming in C++ Lecture Slides 125/134 (c) pk
6
Template Metaprograms
template< typename NumType, unsigned D, unsigned I > struct origin{
static inline void eval( dpoint<NumType,D>& p ){
p[I] = 0.0;origin< NumType, D, I-1 >::eval( p );
}};
// Partial Template Specializationtemplate <typename NumType, unsigned D> struct origin<NumType, D, 0>{
static inline void eval( dpoint<NumType,D>& p ){
p[0] = 0.0;}
};
const int D = 3;inline void move2origin() { origin<NumType, D, D-1>::eval(*this); };
Food for thought
You can implementIFWHILEFOR
Using metaprogramming. And then use them in your code that needs to run at compile time ☺
For the more challenged: Implement computation of determinant / orientation / volume using metaprogramming. (Extra credit)
Template MetaprogrammingExamples.
/* Fibonacci's Function asC++ Template Metaprogram*/template< unsigned long N > struct Fib
{enum { value = Fib<N-1>::value +
Fib<N-2>::value } ;} ;
struct Fib< 1 >{enum { value = 1 } ;} ;
struct Fib< 2 >{enum { value = 1 } ;} ;
Template Metaprogrammingexamples.
/*Binary-to-Decimal asTemplate Metaprogram*/
template< unsigned long N > struct Bin{enum { value = (N % 10) +
2 * Bin< N / 10 > :: value } ;} ;
struct Bin< 0 >{enum { value = 0 } ;} ;
usigned long const one = binary<1001>::value;
More metaprogramming
Learn and use the Boost MTL Library.
Traits Technique
Operate on “types” instead of dataHow do you implement a “mean”
class without specifying the types. For double arrays it should output doubleFor integers it should return a floatFor complex numbers it should return a complex number
COP 3330 Object Oriented Programming in C++ Lecture Slides 126/134 (c) pk
7
Traits
Template< typename T >struct average_traits{
typedef T T_average;};
Template<>struct average_traits<int>{
typedef float T;}
Traits
average_type(T) = Taverage_type(int) = float
Traits
template<typename T>typename average_traits<T>::T_averageaverage(T* array, int N){
typename avearage_traits<T>::T_averageresult = sum(array,N);
return result/N;}
Sources
C++ Templates: The complete guide by Vandevoorde and Josuttis. Template Metaprogramming by Todd VeldhuizenC++ Meta<Programming> Concepts
and results by Walter E. BrownC++ For Game programmers by Noel
LlopisC++ Primer by Lippman and Lajoie
COP 3330 Object Oriented Programming in C++ Lecture Slides 127/134 (c) pk
1
Advanced C++
For : COP 3330. Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
Piyush Kumar
Source: Lutz Kettner.
The user.
#define private public #define protected public #define class struct
Types of users
We can distinguish between to kinds of protection a design can provide:
an user that makes occasionally mistakes an user that willingly tries to get around the protection mechanism
Const correctness
// the pointer, the data it refers to// ---------------------------------------
int* p; int* const q;
const int* r; const int* const s;
Revision.
// the pointer, the data it refers to// ---------------------------------------
int* p; // non-const non-constint* const q; // const non-const
const int* r; // non-const constconst int* const s; // const const
Const declaration
struct A { const int i; A() : i(42) {}
};
This pointer and const.
struct C { // hidden parameter: T* const this;
void foo(); // hidden parameter: const T* const this;
void bar() const; };
COP 3330 Object Oriented Programming in C++ Lecture Slides 128/134 (c) pk
2
Make Temporary Return Objects in C++ Classes Const
L-values: can be used for the left side of an assignment, they are non-const. R-values: cannot be used for the left side of an assignment. . They are const. For example the post-increment operator requires an l-value, but is itself an r-value.
Make Temporary Return Objects in C++ Classes Const
Thus, we cannot write: int i; i++ ++; // second ++ forbidden! Or i++++;Error: error.cpp:5: error: non-lvalue in increment
But: struct A {
A operator++ (int); // the post increment operator
}; Now, lets try: A a; a++++; //compiles!
Make Temporary Return Objects in C++ Classes Const
It works, because a++ returns a temporary object of type A. But it probably does not do what one would expect. Since the second ++ works on a temporary object, a itself gets only incremented once.We can forbid the second increment explicitly by making the return type, the type of the temporary object, const. This should be considered for all similar temporary return types.
struct A { // the post increment operatorconst A operator++ (int);
};
Empty Classes
#include <iostream>
using namespace std;
struct X {};
int main(){cout << sizeof(X) << endl;return 0;
}
C++ classes are often “empty”!
Empty Classes
#include <iostream>
using namespace std;
struct X {};
class Y:public X {};
int main(){cout << sizeof(X) << endl;cout << sizeof(Y) << endl;return 0;
}
EBCO: Empty base class Optimization
Polymorphism
Recap: Ability to associate different specific behaviors with a single generic notation.(Many forms or shapes)What you have seen:
Dynamic Polymorphism
COP 3330 Object Oriented Programming in C++ Lecture Slides 129/134 (c) pk
3
Dynamic Polymorphism Example Static Polymorphism
#include "coord.hpp"
// concrete geometric object class Circle// - \bfseries not derived from any classclass Circle {
public:void draw() const;Coord center_of_gravity() const;//...
};
// concrete geometric object class Line// - \bfseries not derived from any classclass Line {
public:void draw() const;Coord center_of_gravity() const;//...
};
Static Polymorphism#include "statichier.hpp"#include <vector>
// draw any GeoObjtemplate <typename GeoObj>void myDraw (GeoObj const& obj){
obj.draw(); // call draw() according to type of object}
// process distance of center of gravity between two GeoObjstemplate <typename GeoObj1, typename GeoObj2>Coord distance (GeoObj1 const& x1, GeoObj2 const& x2){
Coord c = x1.center_of_gravity() - x2.center_of_gravity();return c.abs(); // return coordinates as absolute values
}
// draw homogeneous collection of GeoObjstemplate <typename GeoObj>void drawElems (std::vector<GeoObj> const& elems){
for (unsigned i=0; i<elems.size(); ++i) {elems[i].draw(); // call draw() according to type of element
}}
Static Polymorphismint main(){
Line l;Circle c, c1, c2;
myDraw(l); // myDraw<Line>(GeoObj&) => Line::draw()myDraw(c); // myDraw<Circle>(GeoObj&) => Circle::draw()
distance(c1,c2); // distance<Circle,Circle>(GeoObj1&,GeoObj2&)distance(l,c); // distance<Line,Circle>(GeoObj1&,GeoObj2&)
// std::vector<GeoObj*> coll; // ERROR: no heterogeneous// collection possible
std::vector<Line> coll; // OK: homogeneous collection possiblecoll.push_back(l); // insert linedrawElems(coll); // draw all lines
}
Static Polymorphism
All types must be determined at compile time.Heterogeneous collections can no longer be handled transparently.Generated code is potentially faster than dynamic polymorphism.
CRTP: Curiously recurring template pattern
General class of techniques that consists of passing a derived class as a template argument to one of its own base classes.
// The Curiously Recurring Template Pattern (CRTP) class derived : public base<derived> {
// ... };
COP 3330 Object Oriented Programming in C++ Lecture Slides 130/134 (c) pk
4
CRTP// The Curiously Recurring Template Pattern// (CRTP)
template <typename Derived>class CuriousBase {
//…
};
class Curious : public CuriousBase<Curious> { // ... // Only valid if the size of CuriousBase<Curious>// can be determined independently of Curious.
};
Who is my parent? CRTP: Alternative outline.
// The Curiously Recurring Template Pattern// (CRTP)
template <typename Derived>class CuriousBase {
//…
};
template <typename T>class CuriousT : public CuriousBase<CuriousT<T> > {
// ...
};
CRTP: Alternative outline.// The Curiously Recurring Template Pattern// (CRTP)
template < template<typename> class Derived >class MCuriousBase {
//…
};
template <typename T>class MoreCuriousT : public MCuriousBase<MoreCuriousT> {
// ...
};
CRTP Concrete Example Counting Objects
#include <stddef.h>
template <typename CountedType>class ObjectCounter {private:static size_t count; // number of existing objects
protected:// default constructorObjectCounter() {
++count;}
// copy constructorObjectCounter (ObjectCounter<CountedType> const&) {
++count;}
// destructor~ObjectCounter() {
--count;}
public:// return number of existing objects:static size_t live() {
return count;}
};
// initialize counter with zerotemplate <typename CountedType>size_t ObjectCounter<CountedType>::count = 0;
A Generic solutionto object counting.
CRTP Concrete Example Counting Objects
#include "objectcounter.hpp"#include <iostream>
template <typename CharT>class MyString : public ObjectCounter<MyString<CharT> > {
//...};
int main(){
MyString<char> s1, s2;MyString<wchar_t> ws;
std::cout << "number of MyString<char>: "<< MyString<char>::live() << std::endl;
std::cout << "number of MyString<wchar_t>: "<< ws.live() << std::endl;
}
CRTP and the current assignment
the graph knows the node and the edge class that are supposed to work together, and therefore the graph class passes itself as template argument to both types.
COP 3330 Object Oriented Programming in C++ Lecture Slides 131/134 (c) pk
5
Another CRTP application
Implement Inequality in terms of equality.
class A {public:
bool operator == (const A& a) const;bool operator != (const A& a) const {
return ! (*this == a);}// ...
};
Another CRTP application
Implement Inequality in terms of equality.
template <class T>class Inequality {public:
bool operator != (const T& t) const {return ! (static_cast<const T&>(*this) == t);
}};
class A : public Inequality<A> { public:
bool operator == (const A& a) const; };
More CRTP usage.
The same technique can be used to implement a base class for iteratorsthat contains all those small member functions that are defined in terms of a much smaller set of member functions.
Proxy Classes
Is this legal?
int data[10][20];
void processInput(int dim1, int dim2){int data[dim1][dim2];…
}
…
int *data = new int[dim1][dim2];
Proxy classes
A dynamic two-dimensional array of integers could be declared in C++ as follows: class Array2D {
public: Array2D( int dim1, int dim2); // ...
};
COP 3330 Object Oriented Programming in C++ Lecture Slides 132/134 (c) pk
6
Proxy Classes
Of course, in a program we would like use the array similar to the builtin(static) two-dimensional arrays and access an element as follows:
int main() {
Array2D a(5,10); // ... int i = a[2][8]; // …(a[2])[8]…
}
Proxy Classes
However, there is no operator[][] in C++. Instead, we can implement operator[] to return conceptually a one-dimensional array, where we can apply operator[] again to retrieve the element.
Proxy Classesclass Array1D {public:
Array1D( int dim);int operator[](int i);// ...
};class Array2D {public:
Array2D( int dim1, int dim2);Array1D& operator[](int i);// ...
};
The intermediate class Array1D is called proxy class, also known as surrogate [Item 30, Meyers97].
Proxy classes
Conceptually, it represents a one-dimensional array.In this application we surely do not want to copy the elements to actually create a one-dimensional array. The proxy class will just behave as if it is an one-dimensional array and internally it will use a pointer to the two-dimensional array to implement its operations.
Double Dispatch
is a mechanism that dispatches a function call to different concrete functions depending on the runtime types of multiple objects involved in the call.
Lookup (Myers Item 31, More effective C++)
Smart pointers
I shot an arrow into the air, It fell to earth, I know not where.
“The Arrow and the Song”H. W. Longfellow
COP 3330 Object Oriented Programming in C++ Lecture Slides 133/134 (c) pk
7
Smart Pointers: auto_ptr
Typical pointer usage.
Source of trouble!
void f() {MyClass *ptrmyclass = new MyClass;// … perform some operatorsdelete ptrmyclass;
}
What if you forgot a return in the middle?
Smart Pointers: auto_ptr
A return in the middle of the function.An exception thrown.
Or else the function has to catch all exceptions.
How do we avoid resource leaks?Recap: valgrind? ☺
Smart Pointers: auto_ptr
// Fixing the last program : Complicated.
void f(){myclass ptr = new myclass;
try {…}
catch( … ){delete ptr;throw; // rethrow the exception
}
delete ptr;}
Smart Pointers: auto_ptr
// header for auto_ptr#include <memory>
void f(){// create and initialize an auto_ptrstd::auto_ptr<myclass> ptr(new myclass);// … perform some operators
}
► delete and catch are no longer necessary!► The smart pointer can free the data to which it points whenever the
pointer itself gets destroyed.► An auto_ptr is a pointer that serves as an owner of the object to which
it refers to. ► As a result , the object gets destroyed when its auto_ptr gets destroyed.► A requirement of auto_ptr is that its object has only one owner.
auto_ptr
Has much of the same interface as an ordinary pointer ( operator *, operator -> )Pointer arithmetic (such as ++) is not defined. Note:
std::auto_ptr<myclass> ptr1(new myclass); // OKstd::auto_ptr<myclass> ptr1 = new myclass; // Error
Misusing auto_ptrS.
Cannot share ownerships.Are not provided for arrays.
They call delete and not delete[]Do not do reference counting.Do NOT meet the requirements for container elements.
When a auto_ptr is copied/assigned the source auto_ptr gets modified! Because its transfers its value rather than copying it.
COP 3330 Object Oriented Programming in C++ Lecture Slides 134/134 (c) pk