Sunteți pe pagina 1din 134

Coding Standards

Coding Standards. | Compile cleanly (no warnings)


z Use multiple compilers. gcc/icc suites
are installed.
| Makefiles are required for each
For : COP 3330.
project.
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330

Piyush Kumar

Coding Standards Code Review

| Use of svn is mandatory. (version | Re-Read code. More eyes will help
control) make better quality. Read code from
z “The palest of ink is better than the best memory”
z Don’t break the build. The code in the version control
good programmers. You’ll learn and
system (svn) should always compile. benefit.
| Lot of svn tutorials on the web.
| It’s best to do code reviews in writing,
z http://artis.imag.fr/~Xavier.Decoret/res
ources/svn/index.html a simple e-mail can suffice.
z http://centerstageproject.com/wiki/inde
x.php/SVN_Tutorial

Correctness Optimization: Making it fast.

| Correct is better than fast. | “Premature optimization is the root of


| Simple is better than complex. all evil”. Don’t optimize prematurely.
| Prefer clarity over cuteness.

| Write code for people first, then | Remember, “It is far easier to make a
machines. correct program fast than to make a
fast program correct”.

COP 3330 Object Oriented Programming in C++ Lecture Slides 1/134 (c) pk
1
Global variables. Coding Style

| Minimize global and shared data. | Prefer compile and link time errors to
z Example. You are not allowed to use run time errors.
“static” keyword in your code (till | Use “const” proactively.
asked). | Avoid macros.
z Information Hiding: Don’t expose | Avoid Magic numbers.
internal information from an entity that | Declare variables as locally as
provides an abstraction. possible.
| Always initialize variables.

Coding Style In the end…

| Avoid long functions (Max number of | Your software should be:


lines in a function = 25). Each line to z Expandable
be less than 80 characters. z Maintainable
| Make header files self-sufficient. z Understandable
| Always write “#include” guards. z Stable
z And preferably built/tested/reviewed
by more than one person…

COP 3330 Object Oriented Programming in C++ Lecture Slides 2/134 (c) pk
2
Documentation Generators

Doxygen Tutorial | A documentation generator is a


programming tool that generates
documentation intended for
programmers (API documentation) or
For : COP 3330. end users (End-user Guide), or both,
Object oriented Programming (Using C++) from a set of specially commented
http://www.compgeom.com/~piyush/teach/3330
source codes.

Piyush Kumar

Commenting programs Why?

zDoxygen is a documentation | Doxygen is very useful for maintaining


generator for C++, C, Java, Objective- and understanding your own larger
C, Python, and to some extent PHP, projects as well as useful
C# and D. documentation for others who use
z Its highly portable. your code.
(Windows/unix/linux/mac)
z KDevelop has builtin support for
Doxygen.

How? Configuration File

| For each project that uses Doxygen, | Well documented, you just need to fill in the
you must create a configuration file. blanks.
| Main things to set
| “doxygen –g” creates a example
z PROJECT_NAME = MyProject
configuration file called “Doxyfile”
z OUTPUT_DIRECTORY = ./doc
| “doxygen [configfile]” will create the z INPUT = ./src ./include
documentation for your code as per z FILE_PATTERNS = *.cpp *.hpp
your configuration specs. z GENERATE_HTML = YES
z EXTRACT_ALL = YES

COP 3330 Object Oriented Programming in C++ Lecture Slides 3/134 (c) pk
1
Documenting the source. Documenting the source.

| Beginning of file: | Beginning of function.


/*! \brief Prints character ch at the current location
/*! \file dpoint.hpp
* of the cursor.
\brief d-dimensional point class *
* If the character is a newline ('\n'), the cursor should
A d-dimensional point class which is written carefully * be moved to the next line (scrolling if necessary). If
using templates. It allows for basic operations on points * the character is a carriage return ('\r'), the cursor
in any dimension. Orientation tests for 2 and 3 dimensional * should be immediately reset to the beginning of the current
points are supported using * line, causing any future output to overwrite any existing
* output on the line. If backsapce ('\b') is encountered,
<a href="http://www.cs.berkeley.edu/~jrs/">Jonathan's</a> * the previous character should be erased (write a space
code. This class forms the building block of other classes * over it and move the cursor back one column). It is up
like dplane, dsphere etc. * to you how you want to handle a backspace occurring at the
* beginning of a line.
HTML allowed \author <a href="www.compgeom.com/~piyush">Piyush Kumar</a> *
\bug No known bugs. * \param ch the character to print
* \return The input character
*/
*/ int putbyte( char ch );

Creating the frontpage Documentation Rules.


| Example that creates first page of
documentation: (You can add it to the | Each file/function should have a header
main.cpp or main source code file) block.
/**
@mainpage COP 3330 Project 1
| Use descriptive and meaningful names for
variables, constants, and functions.
@author Me and Myself

Here you should tell us about how your project works. How to run,
| Don't just re-express the algorithm in
any special things you have, etc. Also, explain any non-trivial
design decisions you make. If you are working with a partner, clearly
English; tell us why you're doing something.
State what is each person’s contribution. You should
also comment on the stability of your code. Any big bugs should be listed
here. Basically, anything that you think we need to know in general about
your project should go here. Right: For each name in the array, extract the lastname.
Any additional comments you want to make can go here. Did you like the Wrong: Set i to 0. Loop from 0 to 10. Call strchr() on a[i],
project? Was it too hard, too easy? My TA smells bad. Well, you get looking for the first ' ' character. Return the pointer
the idea.
the character immediately following the ' '.
This initial documentation here should be removed.
Or else you loose points.

*/

Documentation Rules
| For each project, create a directory
structure like this:
prj_?\
Doxyfile Created using doxygen –g
Makefile Modify it after creation.
README
bin\
data\
doc\
include\
src\

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
2
Setting up svn

SVN Tutorial | Once you receive teamXY.cer


z Save it in ~/svncert directory
z Run /tmp/bin/svncertinstall
z [Read the emailed instructions]

| Run
For : COP 3330.
svn ls https://svn.cs.fsu.edu/repos/team1
Object oriented Programming (Using C++)
z lists all files in your repository. (empty)
http://www.compgeom.com/~piyush/teach/3330

Piyush Kumar

svn mkdir/rm svn importing projects


piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1>ls -la
$ svn mkdir file://svn.cs.fsu.edu/repos/team1/prj_1 -m total 132
"Create project directory" drwx------ 8 piyush CS-Faculty 4096 Aug 30 22:08 .
Committed revision 1. drwx------ 4 piyush CS-Faculty 4096 Aug 30 22:08 ..
drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 bin
$ svn ls file://svn.cs.fsu.edu/repos/team1 drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 data
prj_1 drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 doc
$ svn rm file://svn.cs.fsu.edu/repos/team1/prj_1 -m “Delete -rw------- 1 piyush CS-Faculty 47593 Aug 30 22:08 Doxyfile
project directory“ drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 include
-rw------- 1 piyush CS-Faculty 96 Aug 30 22:08 Makefile
Remark: The -m flag is used to give a log message for the -rw------- 1 piyush CS-Faculty 39 Aug 30 22:08 README
action. Log messages are enforced by svn. drwx------ 3 piyush CS-Faculty 4096 Aug 30 22:08 src

piyush@linprog4.cs.fsu.edu:~/cop3330>svn import /home/faculty/piyush/


cop3330/prj_1/ https://svn.cs.fsu.edu/repos/team1/prj_1 -m 'Initial import'

svn importing projects Cleaning and checking out.


piyush@linprog4.cs.fsu.edu:~/cop3330>svn import /home/faculty/piyush/
cop3330/prj_1/ https://svn.cs.fsu.edu/repos/team1/prj_1 -m 'Initial import' piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1>cd ..
piyush@linprog4.cs.fsu.edu:~/cop3330>rm -rf prj_1/
Adding /home/faculty/piyush/cop3330/prj_1/include piyush@linprog4.cs.fsu.edu:~/cop3330>svn co https://svn.cs.fsu.edu/repos
Adding /home/faculty/piyush/cop3330/prj_1/include/example.hpp /team1/prj_1/
Adding /home/faculty/piyush/cop3330/prj_1/Doxyfile A prj_1/Doxyfile
Adding /home/faculty/piyush/cop3330/prj_1/doc A prj_1/include
Adding /home/faculty/piyush/cop3330/prj_1/src A prj_1/include/example.hpp
Adding /home/faculty/piyush/cop3330/prj_1/src/main.cpp A prj_1/doc
Adding /home/faculty/piyush/cop3330/prj_1/src/Makefile A prj_1/src
Adding /home/faculty/piyush/cop3330/prj_1/bin A prj_1/src/main.cpp
Adding /home/faculty/piyush/cop3330/prj_1/data A prj_1/src/Makefile
Adding /home/faculty/piyush/cop3330/prj_1/README A prj_1/bin
Adding /home/faculty/piyush/cop3330/prj_1/Makefile A prj_1/data
A prj_1/Makefile
Committed revision 6. A prj_1/README
piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1> Checked out revision 6.
piyush@linprog4.cs.fsu.edu:~/cop3330>cd prj_1
piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1>

COP 3330 Object Oriented Programming in C++ Lecture Slides 5/134 (c) pk
1
The extra .svn Working with the project
piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1>ls -la
total 132 $ svn add src/class.h src/class.cpp
drwx------ 8 piyush CS-Faculty 4096 Aug 30 23:02 .
drwx------ 4 piyush CS-Faculty 4096 Aug 30 23:02 .. A src/class.h
drwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 bin
drwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 data A src/class.cpp
drwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 doc
-rw------- 1 piyush CS-Faculty 47593 Aug 30 23:02 Doxyfile $ svn commit –m “Added two files”
drwx------ 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 README
drwx------ 3 piyush CS-Faculty 4096 Aug 30 23:02 src
drwx------ 7 piyush CS-Faculty 4096 Aug 30 23:02 .svn
piyush@linprog4.cs.fsu.edu:~/cop3330/prj_1>

Working with the project Working with the project

| Checkout a fresh copy of the project | Do not add .o or executable files to


every time you start working. the svn server.
| Edit/change it. | Only source code.
| Resources:
| Use svn add/rm commands if you
add/delete files to the project | http://artis.imag.fr/~Xavier.Decoret/res
ources/svn/index.html
| Use svn commit command to save
| http://svnbook.red-
your changes (use this often with a
bean.com/nightly/en/svn-book.html
meaningful –m comment)

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
2
Compiling programs

Make Tutorial | Single source file code:


z g++ -g –Wall main.cpp –lm –o main

| Multiple sources [a,b]


z g++ -g –c –Wall a.cpp
For : COP 3330. z g++ -g –c -Wall b.cpp
Object oriented Programming (Using C++) z g++ -g –o main a.o b.o -lm
http://www.compgeom.com/~piyush/teach/3330

Piyush Kumar

Compiler flags Compilation


| -c
Separate compilation flag. Will produce a ``.o'' file only,
| Multi stage process
z g++ -g main.cpp –lm –o main
without linking.
| -g • g++ -g -c main.cpp –o main.o
The application will have full debug capabilities, but • g++ -g main.o main
almost no optimization will be performed on the z Compiling and Linking
application, leading to lower performance.
| -Wall • Compilation : Produces object code
Enable all warnings.
(main.o)
| -o filename • Linking : Produces executable by linking a
Write output to file. collection of object files and libraries.
For more options: “man g++”

A Typical Software Project Make


| Has 10s to 100s of source files | Make is not tied to any particular
| Multiple directories language.
| Multiple authors
| Make figures out automatically which
| Flags : Differ with compilation
z Debugging flags (-g) files it needs to update, based on
z Optimization flags (-O6 –malign-double) which source files have changed.
z Release Vs Test builds. | Make enables the end user to build
| Make: A tool to automate the build process. and install your package without
z Other cool build tools: CMake, knowing the details of how that is
automake/autoconf, scons.
done.

COP 3330 Object Oriented Programming in C++ Lecture Slides 7/134 (c) pk
1
Make and Makefiles An example

| “make” command reads “makefile” | Main.cpp Æ Uses functions from other


in the current directory for instructions source files and is the main program.
for the build process. | Hello.cpp Æ Function definition.
| If you want to give it a specific file for | Sumof.cpp Æ Function definition.
input, say Makefile-1 use | Functions.hpp Æ Function
z make –f Makefile-1 declarations.

Download code from: http://www.compgeom.com/~piyush/teach/3330/examples/makex.tar.gz


Use “tar zxf makex.tar.gz” to untar files.

An Example: Makefile-0 An Example: Makefile-0

| Running Make | The basic makefile is composed of “rules”:


z make -f Makefile-0 target: prerequisites Other targets
Or source files
g++ main.cpp hello.cpp <tab> system command
sumof.cpp -o hello
z make | Makefile-0
<reads default: Makefile>
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.

Targets, Prereqs and


Another Example: Makefile-1
commands
| Makefile-1 Dependencies
| Target: is usually the name of a file that is
generated by a program; examples of targets all: hello

are executable or object files. A target can also hello: main.o sumof.o hello.o
be the name of an action to carry out, such as Command g++ main.o sumof.o hello.o -o hello

`clean' main.o: main.cpp


g++ -c main.cpp Prerequisites /
| A prerequisite is a file that is used as input to
Dependencies.
create the target. A target often depends on sumof.o: sumof.cpp
g++ -c sumof.cpp
several files.
hello.o: hello.cpp
| A command is an action that make carries out. g++ -c hello.cpp
Wildcards.
clean:
rm -rf *o hello *.exe
Put a tab before the command
“make –f Makefile-1 clean” cleans up your directory except source code.

COP 3330 Object Oriented Programming in C++ Lecture Slides 8/134 (c) pk
2
Make Another Example: Makefile-2
| Makefile-2 Comments in makefile.
| Only makes out of date prerequisites.
# The variable CC will be the compiler to use.
hello: main.o sumof.o hello.o CC=g++
Variables
g++ main.o sumof.o hello.o -o hello # CFLAGS will be the options I'll pass to the compiler.
CFLAGS=-c -Wall -g

all: hello

| How to decide whether “hello” is out Using hello: main.o sumof.o hello.o
$(CC) main.o sumof.o hello.o -o hello
Variables
of date? main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
z It is out of date if it does not exist, sumof.o: sumof.cpp
or $(CC) $(CFLAGS) sumof.cpp

z if either main.o , sumof.o or hello.o are more recent than it. hello.o: hello.cpp
$(CC) $(CFLAGS) hello.cpp

clean:
If “hello” is out of date, make executes the command ‘g++ main.o …’ rm -rf *o hello *.exe

Makefile targets Make: How does it work?

| Expected targets in makefiles | make reads the makefile in the current


z make all directory and begins by processing
• Compile everything.
the first rule. (in our case: all)
| but before make can fully process this
z make install
rule, it must process the rules for the
• Install your software.
files that ‘all’ depends on, which in this
z make clean case are the object files.
• Clean intermediate files and executables.
| Each of these files is processed
according to its own rule.

Make: How does it work? Make: Wrap up

| For any rule, the recompilation must | make –j2


be done if the prerequisites are more z Uses 2 processors for the build process.
recent than the target, or if the | More info:
target/object file does not exist. z http://www.gnu.org/software/make/manual/ht
ml_node/index.html
z man make
z Example :
http://www.compgeom.com/~piyush/teach/33
30/examples/makex.tar.gz

COP 3330 Object Oriented Programming in C++ Lecture Slides 9/134 (c) pk
3
Administrative Trivia

C++ Tour About me:


Piyush Kumar
Phone: 645-2355
For : COP 3330. Email: piyush@cs.fsu.edu
Object oriented Programming (Using C++) Office hours: Tuesday 4:30 to 5:30.
http://www.compgeom.com/~piyush/teach/3330

TAs: Ryan Walega and Yuhua Zhu

More details on the course information sheet.


Piyush Kumar

Your ID Announcement

You have been assigned an ID on the | First Quiz : On Thursday. Will test
Blackboard. You should know your ID. your background knowledge.
| Revise your previous C/C++ material.
| Your first assignment will be posted
Your ID will be used to setup your
on Wednesday.
Subversion (svn) repository.
z Will be due on Tuesday, 9/5/06.
z You are required to setup your svn
http://www.compgeom.com/~piyush/teach/3330/handouts/SVN_Setup.pdf repository by this Thursday. The
submission will use the svn server.

Announcement

| Blackboard Discussions already


setup.
C++ Tour
| Make sure you submit the pre-req
form today before you leave.
| SVN generation of certificates (demo).

COP 3330 Object Oriented Programming in C++ Lecture Slides 10/134 (c) pk
1
Why learn C++? C++ Features

| Ubiquitous | Supports data security


| Object Oriented | Prevents accidents with data
z Easier large scale projects | Helps code reuse.
z Resuability | Lets you use operators the way you
| High Performance like.
| Allows multiple functions/operators
with the same name.

When to use C++? When not to use C++?

| Large projects | Small system programs.


| System applications | Fast prototyping.
| Graphics | Web-based applications (Perl/Python)
| Data Structures
| Speed is an issue?
| Changes in functionality required.
| Need exceptions and error handling?
| Want to speed up your scripts?

Compiling/Running
Important definitions
programs
| Algorithm: Ordered set of actions to | Single source file code:
accomplish a certain task. z g++ -g –Wall simple.cpp –o simple

| Program: Implementation of | Compilation / Editing Demo


algorithms. z Editors: vim / xemacs
| Compiler, function, library, bug. z Xemacs tutorial:
int main() {
hanson.geog.udel.edu/cmg/Handouts/xema
| Variables, constants. cs_tutorial.pdf
return 0;
| Keywords (if, while, for,…) z Vi/vim
} tutorial :
http://www.biochem.ucl.ac.uk/~mckenzie/vim
| Data Types. (long, int, …)
/tutorial.html

COP 3330 Object Oriented Programming in C++ Lecture Slides 11/134 (c) pk
2
simple.cpp simple.cpp
int main() // Function Declaration | On Unix: echo $?
// Function body follows | On Windows: echo %ERRORLEVEL%

{ // Block of statements begins.

return 0;

} // Block ends.

System dependent

Simple.s (using g++ -O –S simple.cpp) Simple.s (using VC++ 05 compiler)


//{
.file “simple.cpp" 00411360 push ebp
.def ___main; .scl 2; .type 32; .endef 00411361 mov ebp,esp
.text 00411363 sub esp,0C0h
.align 2 00411369 push ebx
.p2align 4,,15 0041136A push esi
.globl _main 0041136B push edi
0041136C lea edi,[ebp-0C0h]
.def _main; .scl 2; .type 32; .endef
00411372 mov ecx,30h
_main: 00411377 mov eax,0CCCCCCCCh
pushl %ebp ; Save base pointer 0041137C rep stos dword ptr es:[edi]
movl $16, %eax // return 0;
movl %esp, %ebp ; Set up stack frame for debugger 0041137E xor eax,eax
subl $8, %esp ; Save space on the stack //}
andl $-16, %esp ; Align stack pointer 00411380 pop edi
call __alloca ; Platform dependent call 00411381 pop esi
00411382 pop ebx
call ___main ; Platform dependent call
00411383 mov esp,ebp
leave ; free space, pop ebp, esp… 00411385 pop ebp
xorl %eax, %eax ; zero eax 00411386 ret
ret ; return control to calling procedure.

G++ Compilation.
preprocessing (to expand macros)
|

|
z Try “cpp simple.cpp > simple.i”
compilation (from source code to assembly language)
Introduction to C++
z Try “g++ -Wall –S simple.i”
| assembly (from assembly language to machine code)
z Try “as simple.s -o simple.o”
| linking (to create the final executable)
z Try “gcc simple.o”
z 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

COP 3330 Object Oriented Programming in C++ Lecture Slides 12/134 (c) pk
3
Organization C++ is a superset of C.

| C++ = C + objects + … | Features present in C are also present in


| Main Theme : Objects C++
| Class Vs Object | C++ is a object oriented programming
| Data Hiding and Abstraction language ( C++ = c + objects + …)
| Encapsulation | OOP is about objects which contain data
| Inheritance and functions to manipulate that data.
| Operator and Function Overloading | A single unit that contains data and
| Polymorphism. functions that operate on the data is called
| Generic Programming an object.

Main Theme: objects OOP

| C++ enables you to focus on discrete | Based on concept of objects and


objects that contain both data and classes.
functions to manipulate that data.
| Objects: Represent entities with
| Instead of data and functions as
related state and behaviour
separate entities as was the case in
C. z Instances of a class
| Application = Collection of Objects. | Classes: Define common
z Makes complex programs easy to characteristics of similar objects.
code.

Objects/Classes Object / Class Example


Car Class
Attributes: Behavior:
| Objects are reusable self-contained Manufacturer Accelerate
programming modules with data and Model Break
Color Steer
functions. Engine Tune Up

| Classes are blue-print for objects with


common properties, attributes,
operations and behaviors.

The principal building blocks of OO programs are classes and objects.

Objects: Instantiations of classes.

COP 3330 Object Oriented Programming in C++ Lecture Slides 13/134 (c) pk
4
Another Object / Class Fundamental building block
example of OOP: A Class
class Point { | A class defines a data type, much like
int _x, _y; // point coordinates a struct would be in C.
public: // begin interface section | A class is a source code for an object

void setX(const int val);


(hence it has both data+member
void setY(const int val); functions)
int getX() { return _x; }
int getY() { return _y; }
Attributes
}; …

Point tpoint; // defines an object tpoint class


Methods

Fundamental building block


Data Hiding
of OOP: A Class
| Objects contain information
| You can imagine that int is a class
| Only part of the information contained
that has member functions called
in the object might be presented to the
operator++, etc.
user.
| An object usually means an instance
| Rest is concealed.
of a class
z After the declaration int i; we say that
Engine
"i is an object of type int."
Interface

Data Hiding Data Hiding


| Internal dynamics are not visible to | Allows data to be accessed by certain
the user. functions class Point { // private
// concealed info
| Data hiding is done by using the
int _x, _y; // point coordinates
“private” keyword in the class public: // begin interface section

definition. void setX(const int val);


void setY(const int val);
int getX() { return _x; }
int getY() { return _y; }
Engine
};
Interface
Point tpoint; // defines an object tpoint

tpoint._x = 5; // ILLEGAL

COP 3330 Object Oriented Programming in C++ Lecture Slides 14/134 (c) pk
5
Data Abstraction Data Encapsulation

| DA is a programming technique where | Combine lower level elements to form


one separates the interface from the a new higher level entity.
implementation | Grouping of attributes and behaviors
| Class designer worries about the to form an object.
implementation
C++ vector type is an example of both data abstraction
| Programmers only need to know the and Data encapsulation
interface.
String s; s.rfind(‘\’);

OOP : Inheritance Inheritance

| Many classes have common attributes. | Children inherit traits from their
| These classes can be arranged in a parents.
hierarchy.
| When a class is inherited all the
| Inheritance enables you to reuse code and functions and data member are
add data and functionality without making
any changes to the existing code.
inherited, although not all of them will
z For example, objects can inherit
be accessible by the member
characteristics from other objects. functions of the derived class.

Inheritance Inheritance

| protected/public members of the base | Derived classes are specialized form


class are accessible to the derived of their base class.
class | Abstract class : A base class that is
| private members are not. undefined and unimplemented.
class vehicle {
protected:
char colorname[20]; class Car: public vehicle {
int number_of_wheels;
public:
protected:
vehicle(); char type_of_fuel;
~vehicle(); public:
void start(); Car();
void stop();
void run(); };
};
Subclass or derived class
Super class or Base class

COP 3330 Object Oriented Programming in C++ Lecture Slides 15/134 (c) pk
6
Multiple definitions…? Operator Overloading

| C++ allows for the same function (or | C++ gives you the power to define operators
overloaded operator) to have multiple on user defined types.
defintions. | Example:
z Swap(int& I, int& j); z MyMatrix m = m1 + m2; // cant do this in C.
z Swap(string& I, string& j); | Overloading is a type of polymorphism.
z Swap(double& I, double& j);
| Not all operators can be overloaded in C++.
a.k.a. Function overloading.

Polymorphism Methods:
Draw() Polymorphism Methods:
Draw()
MyShape Erase() MyShape Erase()

2DShape 3DShape 2DShape 3DShape

Circle Square Triangle Sphere Cube Tetrahedron Circle Square Triangle Sphere Cube Tetrahedron

| Base Class MyShape establishes the | Overriding: When a child class extends the
functionality of its parent class.
common interface to anything | Polymorphism allows the programmer to
inherited from MyShape. implement different draw/erase methods for
derived classes.
| All shapes can be drawn and erased.
| Sphere and Cube have the same function
draw() with different functionality.

Polymorphism Methods:
Draw() Polymorphism
MyShape Erase()

2DShape 3DShape
| Using operators and functions in
different ways depending on what
Circle Square Triangle Sphere Cube Tetrahedron they are operating on is called
polymorphism.
| No matter what shape the object is, z Static
one can use the “draw” method to z Dynamic
draw it correctly.
| The concept builds upon
encapsulation and inheritance.

COP 3330 Object Oriented Programming in C++ Lecture Slides 16/134 (c) pk
7
Generic Programming

| Type independent code


| Write 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 Programming


template <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
8
Basic C++ Types
Basic and Library | integer data-types :

Types |
char, short, int, long, unsigned char, unsigned short,…
floating point data-types :
float, double, long double
| logical data-type : bool
z bool constants : true, false
For : COP 3330.
| character data-type : char and wchar_t
Object oriented Programming (Using C++) z Char constants in single quotes : ’a’
http://www.compgeom.com/~piyush/teach/3330 | text data-type :
string
string constants in double quotes : ”Hello world”

Piyush Kumar

Recommended assignments:
2.4/2.7/2.8/2.9

Basic C++ Types Basic Arithmetic types


Type Low High Digits of Bytes
| void Precision
char -128 127 - 1
z Return type for a function with no
return value short -32768 32767 - 2

z void pointers int -2147483648 2147483647 - 4

| unsigned and signed integers long -2147483648 2147483647 - 4

z unsigned char x = -1; ? float 3.4x10-38 3.4x1038 7 4


z unsigned short int x = -1; ? double 1.7x10-308 1.7x10308 15 8

-2 254 long 3.4x10-4932 3.4x104932 19 10


Wrap around effect. double
-1 0 255
Machine dependent.

Variable Naming Hungarian naming

| Read about hungarian naming: | Three parts


| http://en.wikipedia.org/wiki/Hungarian_notati z Base Type
on
z One or more prefixes
| http://www.idleloop.com/hungarian/hungaria
z Qualifier
n.html
| http://www.totse.com/en/technology/comput
er_technology/hungnote.html
| Use them in your next assignment onwards.

COP 3330 Object Oriented Programming in C++ Lecture Slides 18/134 (c) pk
1
Hungarian Base Types Prefixes
| Specifies the type of the variable being named | Go in front of the base type
| Somewhat standard list:
| Not for predefined types z a = Array
| Example: z c = Count
z d = Difference
z wn = Window
z e = Element of an array
z scr = Screen z g = Global variable
z fon = Font z h = Handle
z i = index to array
z pa = Paragraph
z m = Module-level variable
| Example: z p(np, lp) = Pointer (near or long)
z WN wnMain=NULL; | Describes how the variable will be used.
| Examples
z FONT fonUserSelected = TIMES_NEW_ROMAN; z Array of windows: awnDialogs
z Handle to a window: hwnMyWindow
z Number of fonts: cfon

Qualifiers More Examples


| bBusy : boolean
| The rest of the variable name in case | cApples : count of items
you were not using Hungarian | dwLightYears : double word
naming. | fBusy : boolean (flag)
| iSize : integer
| fpPrice: floating-point
| dbPi: double
| pFoo : pointer
| rgStudents : array, or range
| szLastName : zero-terminated string
| u32Identifier : unsigned 32-bit integer
| m_nWheels : member of a class, integer

Variables Variables

| What you should know? | Declaration


z Machine level representation of built in z extern int i;
types. | Definition
z Difference between : ‘a’ and “a” z int i;
z Type of every entity in our program z Is also a declaration
should be known to the compiler.

Type specifier

COP 3330 Object Oriented Programming in C++ Lecture Slides 19/134 (c) pk
2
Recommended
Exercises: 2.15/2.16

Variable Initialization Coding Standards

| Direct initialization | Always initialize your variables


Can be more efficient
• float funity (1.0); for general classes. | Define variables where they are used.
• std::sting all_nines(10,’9’); // #include <string>
| Pick names carefully.
• Happens when a variable is created and
gives the variable its initial value. | Be careful about scopes of variables

| Copy initialization z Global Scope


• float funity = 1.0; z Local Scope
• Assignment involves replacing the current z Statement scope
value of the variable with a new one.

More on this when we do “class” in detail.

Const Qualifier Const qualifier


| for (int Index = 0; Index < 512; ++Index) | Const member functions
| const int ibufSize = 512;
| ibufSize = 0; // error: attempt to write to z Specify which member functions can
const object be invoked on const objects.
| const int I , j = 0; Å What is wrong? Class Rational { …
| Const objects are local to a file by default. public:

| Prefer const to #define const int numerator(void);
z Using const instead of #define allows …
const Rational operator+(const Rational& rhs) const;
much better type checking and }
reduces name space pollution.
const Rational operator+(const Rational& lhs,
const Rational& rhs);

Const qualifier Const qualifier

| Const member functions | Const member functions


z Specify which member functions can z Specify which member functions can
be invoked on const objects. be invoked on const objects.
Class Rational { …
const Rational operator+(const Rational& lhs,
public:
const Rational& rhs);

const int numerator(void);
When operator+ is a member function,

a = b+c is allowed, but what if you want to do
const Rational operator+(const Rational& rhs) const;
a = c + 2;
}
a = 2 + c;
Mixed mode operations are the reason why operators
Rational a,b,c; a = b+c;
are usually defined outside the class.
But does not allow (a+b) = c;

COP 3330 Object Oriented Programming in C++ Lecture Slides 20/134 (c) pk
3
References References

| What is a reference? | A reference is an alias.


z An alternate name for an object. z Int ival = 1024; int &refVal = ival;
z Frequently used for pass by reference. z refVal += 2; // increases ival.
void swap(int& i, int& j) int main()
{ {
| Errors:
int tmp = i; int x, y; z int &refVal2 = 10; // a reference must
i = j; ...
j = tmp; swap(x,y); be initialized.
} ...
} z Int &refVal3;

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.

Const references Const references


#include <iostream>
| A reference that refers to a const using namespace std;
object. int main(void){
z const int ival = 1024; int dval = 100;
const int& ref = dval;
z const int& refval = ival; ref++;
return 0;
z const double& pi = 3.14; // only legal }
for const references
| Errors:
z Int &ref2 = ival; // Non-const reference What is wrong?
to a const object.

Typedef names Back to the C++ Class


Typedef lets us define a synonym for a type.
typedef double wages; | The C++ Class
typedef int exam_score; z Similar to a struct
typedef wages salary; z Defines what objects of a class are (what
typedef int Pounds, Shillings, Pennies, Dollars, Cents;
attributes describe them)
Variable definitions: z Usually contains functionality in addition to
wages wage1,wage2; attributes
exam_score person1, person2; | The Object
-----------------------------------------------------------------------------------
typedef struct { int scruples; int drams; int grains; } WEIGHT;
z An instance of a class
z A variable declared to be of a "class type“
typedef class { | class member: a component of a class; may
public:
int scruples; int drams; int grains;
be either a data item or a function
} WEIGHT;

COP 3330 Object Oriented Programming in C++ Lecture Slides 21/134 (c) pk
4
Class example 2D Point class

| Write a class to represent a two | Data


dimensional point. z Position
| What data attributes do we need? | Operations
| What operations? z Set Position
z Get Position
z Distance from another point

Your first class. Include guards


Using the point2D class
Private
#ifndef POINT2D_HPP
#define POINT2D_HPP

class point2D{ Point2D p,q;


int _x,_y;
Interface p.setX(10); p.setY(10);
public:
void setX(const int val);
void setY(const int val);
q.setX(0); q.setY(10);
int getX();
int getY();
double double_distance(point2D& p);
}; Cout << “Distance between p and q is “
typedef Point2D Cell_tower; << p.distance(q) << endl;
typedef Point2D Cell_phone;

// Implementation goes here…

#endif

Implementing the point2D Implementing the point2D


class. #ifndef POINT2D_HPP
class. #ifndef POINT2D_HPP
#define POINT2D_HPP #define POINT2D_HPP

class point2D{ class point2D{


int _x,_y; int _x,_y;

public: public:
void setX(const int val) { void setX(const int val) ;
_x = val;
} // … Rest of the interface/implementation…
};
// … Rest of the interface/implementation…
}; typedef point2D Cell_tower;
typedef point2D Cell_phone;
typedef Point2D Cell_tower;
typedef Point2D Cell_phone; // Implementation goes here…
void point2D::setX(const int val){ Can be also
// Implementation goes here… _x = val; implemented
} in point2D.cpp
#endif
#endif

COP 3330 Object Oriented Programming in C++ Lecture Slides 22/134 (c) pk
5
Headers Header files
Header file

| Always use #include guards main program point2D.hpp implementation file

| Do not define variables or functions in main.cpp point2D.cpp


headers except #include “point2D.hpp”

z Class definitions Compiler Compiler


z Const objects
z Inline functions main.o point2D.o
| Difference between
z #include <myfile.h> Linker
z #include “myfile.h”
prj_2

Avoiding Multiple Inclusion of


Header Files Using the MyTimer class
| 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 | #include “timer.hpp”
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
MyTimer time_elapsed;
// your code goes here…
#ifndef Preprocessor_Identifier
cout << time_elapsed;
#define Preprocessor_Identifier
.
. h
.
#endif

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
6
C++ IO

C++ IO | All I/O is in essence, done one


character at a time

| Concept: I/O operations act on


For : COP 3330.
streams (sequences) of ASCII
Object oriented Programming (Using C++)
characters
http://www.compgeom.com/~piyush/teach/3330

Piyush Kumar

C++ IO <iostream> vs <cstdio>

| cout standard output stream | More type-safe: With <iostream>, the type of object
being I/O'd is known statically by the compiler. In
sequence of characters printed contrast, <cstdio> uses "%" fields to figure out the
to the monitor types dynamically.
| Less error prone: With <iostream>, there are no
redundant "%" tokens that have to be consistent with
| cin standard input stream the actual objects being I/O'd. Removing redundancy
sequence of characters input removes a class of errors.
from the keyboard | 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
| both cout and cin are data objects printf() and scanf()?!
and are defined as classes | Inheritable: User defined streams possible.

Interactive I/O Example


Namespaces: They provide
a way to avoid name collision.
#include <iostream> Be careful about using this.
#include <iostream>

output data using namespace std; Standard IO library


input data
for C++. Defines two
int main(void){ fundamental types,
executing
Keyboard program Screen istream and ostream.
cout << “Hello World” ;
cout << endl;
return 0;

cin cout }

( type istream ) ( type ostream ) Stream: A flow of characters (1 or 2 bytes long). Can flow in and out of
Files, strings, etc.
class class

COP 3330 Object Oriented Programming in C++ Lecture Slides 24/134 (c) pk
1
Example Example invokes a manipulator function called endl.
endl looks something like this:

ostream& endl( ostream& os)


Ostream object named cout. {
#include <iostream> #include <iostream> os << '\n';
os.flush();
using namespace std; using namespace std; return os;
}
int main(void){ int main(void){

cout << “Hello World” ; cout << endl;


cout << endl; return 0; Equivalent Compiler statement:
return 0; std::cout.operator<<(
Equivalent to: } std::endl(std::cout)
} operator<< (cout, “Hello World”); );
Its calling a friend function of
ostream with input data. Scope Operator for
namespaces.
Uses function declaration (approx):
ostream& operator<<( ostream&, const char * )

Special Output Characters Stream IO headers

\n new line | iostream -- contains basic information


required for all stream I/O operations
\t tab
| iomanip – used for performing formatted I/O
\b backspace with stream manipulators
\r carriage return | fstream – used for performing file I/O
operations
\' single quote
| strstream -- used for performing in-memory
\" double quote I/O operations (i.e., into or from strings in
\\ backslash memory)

A Stream C++ IO Class hierarchy


ios
| A flow of characters.
| Buffers: IO to streams goes thru a istream ostream streambuf

buffer. C++ allows you change the


default behavior of associated buffers. ifstream istringstream ostringstream ofstream

| State: Each stream is associated with


a state indicating various things like if
an error has occurred or not… stringbuf

filebuf

COP 3330 Object Oriented Programming in C++ Lecture Slides 25/134 (c) pk
2
C++ IO Class hierarchy C++ IO Hierarchy
ios
| The ios hierarchy defines the
istream
cin
ostream
cout
streambuf interface of the IO system.
| The streambuf hierarchy defines the
ifstream istringstream ostringstream ofstream implementation of the IO system,
mostly provides the facilities of
buffering and byte-level I/O
stringbuf

filebuf

Formatting with predefined


Other Predefined Streams
streams.
| cerr - the standard destination for | Remember: Due to inheritance,
error messages (often the terminal anything you learn about formatting IO
window). Output through this stream with predefined streams (cin, cout,
is unit-buffered, which means that clog, cerr) also applies to file IO and
characters are flushed after each string IO.
block of characters is sent. | Anything available or defined in the
| clog - like cerr, but its output is ios class is available everywhere in
buffered. the IO subsystem.

Stream IO Example
Inside ios

| << (left-shift operator) | cin >> Variable;


z Overloaded as stream insertion | cout << Variable;
operator | clog << Variable;
| >> (right-shift operator) z Buffered
z Overloaded as stream extraction | cerr << Variable;
operator
z Unbuffered, prints Variable
| Both operators used with cin, cout, immediately.
cerr, clog, and with user-defined | Note: Variable types are available to
stream objects the compiler.

COP 3330 Object Oriented Programming in C++ Lecture Slides 26/134 (c) pk
3
<< operator << operator
| Associates from left to right, and returns a reference to
| << is overloaded to work on built-in its left-operand object (i.e. cout). This enables
types of C++. cascading.
| Outputs “char *” type as a string.
| Can also be used to output user-
| If you want to print the address, typecast it to (void *).
defined types. | Example:
z char name[] = “cop3330”;
| Other interesting examples:
z cout << name << static_cast<void *>( name ) << endl;
z cout << ‘\n’; // newline. z static_cast<void *>( name ) equivalent to ((void *)
z cout << “1+2=” << (1+2) << endl; name) in C except that it happens at compile time.
z cout << endl; // newline.
z cout << flush; // flush the buffer.

Stream insertion: One char. Input Stream


| put member function | >> (stream-extraction)
z Used to perform stream input
z Outputs one character to specified stream z Normally ignores whitespaces (spaces, tabs,
cout.put(‘C'); newlines)
z Returns zero (false) when EOF is encountered,
z Returns a reference to the object that called otherwise returns reference to the object from which it
it, so may be cascaded was invoked (i.e. cin)
cout.put( ‘C' ).put( '\n' ); • This enables cascaded input
cin >> x >> y;
z May be called with an ASCII-valued
expression | >> controls the state bits of the stream
cout.put( 65 ); z failbit set if wrong type of data input
• Outputs A z badbit set if the operation fails

Input Stream : Looping Example Program


#include <iostream>

using std::cout;
while (cin >> fname) using std::cin;
using std::endl;

int main(void) {
“>>” returns 0 (false) when EOF int height = 0, maxheight = 0;
encountered and loop terminates. 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
4
Output istream member function: get

$ ./a.exe | char ch = cin.get();


Enter the heights: (enter end of file to end): 72
89 z Inputs a character from stream (even
54
33
white spaces) and returns it.
68
66
Tallest person's height = 89 | cin.get( c );
z Inputs a character from stream and
stores it in c

istream member function: get istream member function:


get (array_name, max_size) ; getline (array_name, max_size)

char fname[256] char fname[256]


cin.get (fname, 256); cin.getline (fname, 256);

| Read in up to 255 characters and inserts | Same as get, except that getline
a null at the end of the string “fname". If
a delimiter is found, the read terminates. discards the delimiter from the stream.
The array acts like a buffer. The
delimiter is not stored in the array, but is
left in the stream.

istream member functions: istream member functions:


ignore() peek(), putback()
| cin.ignore ( ) ; | char ch = cin.peek ( ) ;
z Discards one character from the input z Peeks into the stream’s next
stream. character.
| cin.ignore (10) ; | cin.putback (‘A’) ;
z Discards 10 characters. z Puts ‘A’ back in the stream.
| cin.ignore(256,’\n’);
z Discards 256 characters or newline,
whichever comes first.

COP 3330 Object Oriented Programming in C++ Lecture Slides 28/134 (c) pk
5
FILE IO Example. Slightly modified
Copy File “first.txt” into “second.txt”. #include <iostream>
#include <fstream>
#include <iostream>
#include <fstream> using namespace std;

using namespace std; int main(void)


{
int main(void) ifstream source("first.txt");
{ ofstream destin("second.txt");
ifstream source("first.txt");
ofstream destin("second.txt"); char ch;
while (source.peek() != EOF){
char ch; source.get(ch);
while (source.get(ch)) destin.put(ch);
destin<<ch; }
return 0; return 0;
} }

C++ IO Class Hierarchy


More IO functions
Revisited
ios
| read()
z cin.read(fname, 255); istream
cin
ostream
cout
• Reads 255 characters from the input
stream. Does not append ‘\0’.
ifstream ofstream
| cout.write(fname,255);
• Writes 255 characters.
istringstream ostringstream
iostream
| gcount: returns the total number of
characters read in the last input
operation.
stringstream fstream

Another example stringstream operations


#include <iostream>
#include <sstream>
#include <string> What if I replace this
with istringstream? | stringstream strm;
using namespace std;
| stringstream strm(mystring);
z Initializes strm with a copy of mystring.
int main() {
int i; | strm.str();
string line; z Returns the content of strm in string format.
while(getline(cin,line)){
stringstream sfstream(line);
while (sfstream >> i){ | strm.str(s);
cout << i << endl;
} z Copies the string s into strm. Returns void.
}
return 0;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 29/134 (c) pk
6
#include <iomanip>
dec, hex, oct, setbase
Stream | oct, hex, dec
Manipulators z Cout << hex << 15;
• Prints ‘F’
| cout << setbase(16) << 15;
z Prints ‘F’ again.

Formatting Output - Integers


Formatting Output - Integers
p.2
| int numstdts = 35533; | we can specify the field width, or number
cout << “FSU has" << numstdts of spaces used to print a value
<< "students."
prints cout << “FSU has" << setw(6)
FSU has35533students. << numstdts << " students."
prints
| default field width == minimum required FSU has 35533 students.
function call
default: what happens when explicit
formatting is not specified prints in field width 6, right-justified

Formatting Output - Integers Formatting Output - Integers


p.3 p.4
| cout << “FSU has" << setw(10) | cout << left; // flip to left justification
<< numstdts << " students."
prints cout << “FSU has " << setw(10)
FSU has 35533 students. << numstdts << "students."
prints
prints in field width 10, right-justified FSU has 35533 students.

prints in field width 10, left-justified

COP 3330 Object Oriented Programming in C++ Lecture Slides 30/134 (c) pk
7
Using the default - Integers p.5
General Rule of Thumb
| Note on field widths: if a field width specified is
too small, or is not specified, it is automatically
expanded to minimum required | When you are printing numeric values in
sentences or after a verbal label, the default
| numstdts = 100; field width usually works well
cout << “FSU has "
<< numstdts << " students." | When you are printing numeric values lined
prints up in columns in a table, it is usually
necessary to call setw to generate well-
FSU has 100 students. formatted output (we will see examples of
this later in the course)
and works for any value of numstdts

Formatting Output - Reals Formatting Output - Reals p.2


| float cost = 5.50; | Setting up real formatting
cout << "Cost is $" << cost
<< "today." // use fixed point notation
prints cout << fixed;
Cost is $5.5today.
// print a decimal point (with whole numbers)
cout << showpoint; ( noshowpoint )
| default
z large values printed in scientific notation these remain in effect until changed explicity, as
does setprecision. setw only changes next value
z if number is whole, no decimal point
printed.
z numbers of digits not under your control

Formatting Output - Reals p.3


You can just do this, once:

| float cost = 5.50; | cout << fixed << showpoint


cout << "Cost is $" << setw(5) << setprecision(2);
<< setprecision(2) << cost
<< " today." and these settings will remain in effect
prints
Cost is $ 5.50 today. throughout your program run

| if no field width is specified, minimum is used,


just as for integers

COP 3330 Object Oriented Programming in C++ Lecture Slides 31/134 (c) pk
8
Formatting Output - char Formatting Output - Strings
| default field width == 1 | default field width == number of
note: setw does have effect on characters in the string
char type data too.
can use setw
char ch = 'Q';
cout << '*' << ch << setw(3) << '*'; cout << setw(10) << "Hello";
prints
prints Hello
*Q *

Useful Output Spacer


Unitbuf manipulator
| const string BLANK = " ";
| If you want to flush every output
cout << setw(10) << BLANK;
z Cout << unitbuf
prints 10 blanks
<< “first”
<< “second”
| consider this:
const char BLANK = ' '; << nounitbuf;
cout << setw(10) << BLANK;
prints 10 blanks!

Example Quiz Manipulators: Rolling your own.


A. 0.1, 1, 1.23457e+009
#include <iostream>
Copy not allowed
B. 0.100000, 1.000000, 1234567936.000000 •How to create our own stream
#include <iomanip> An Example. on ostreams.
C. 1.000000e-001, 1.000000e+000, 1.234568e+009 manipulators?
D. 0.100, 1.000, 1234567936.000 bell
using namespace std; #include <iostream>
E. 0.10000000000000000555 ret (carriage return)
#include <ostream>
int main() { tab
const double tenth = 0.1; endLine
using namespace std;
const float one = 1.0;
const float big = 1234567890.0;
cout << "A. " << tenth << ", " << one << ", " << big << endl; ostream& myendl( ostream& os) {
cout << "B. " << fixed << tenth << ", " << one << ", " << big << endl; os << "test\n";
cout << "C. " << scientific << tenth << ", " << one << ", " << big << endl; os.flush();
cout << "D. " << fixed << setprecision(3) << tenth << ", " << one << ", " << big << endl; return os;
cout << "E. " << setprecision(20) << tenth << endl; }
return 0;
}
int main(void) {
cout << myendl;
return 0;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 32/134 (c) pk
9
Error states
strm::eofbit
Stream Error States |
z if (cin.eof() == true) break; // stream end of file.
| strm::failbit
z if ( cin.fail() == true) break; // stream format error.
| strm::badbit
z If (cin.bad() == true) break; // data lost!
| Goodbit?
z cin.good() = ((!eofbit) && (!failbit) && (!badbit))
z All eofbit, failbit and badbit should be false.
| cin.clear() // makes cin good.

Error States Example Operators for testing.

int ival; z operator!


While ( cin >> ival, !cin.eof() ){ • Returns true if badbit or failbit set
Assert( !cin.bad() , “IO stream corrupted”);
if (cin.fail()){ //bad input
cerr << “Bad data, try again.”;
cin.clear(istream::failbit); // reset the stream z Useful for file processing
continue; • if ( ! readmefile ) cerr << “Error”;
}
// ok to process ival now
} //end of while.

Interactive Input Interactive Input: Example

| Write a prompt int num;


make it friendly and informative char response; prefix

prompt typically contains prefix cout << "Enter a number -> ";
character to signal point at which to cin >> num;
enter input
cout << "Enter Y or N -> ";
| Read value(s) cin >> response;
user types data at keyboard

COP 3330 Object Oriented Programming in C++ Lecture Slides 33/134 (c) pk
10
Interactive Input: Contents of Another C++ Program
Output Window (Hello argv[1])
#include <iostream>
using namespace std;
Enter a number -> 17<return>
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "Usage: hi.exe <name>" << endl;
Enter Y or N -> Y<return> exit (1);
}

cout << "Hello " << argv[1] << endl;


the program will not process the return 0;
}
input until the return key is struck

Control structures

| Statements you should already know :


z While
z For
z If

Recommended Assignments: 1.17, 1.25

COP 3330 Object Oriented Programming in C++ Lecture Slides 34/134 (c) pk
11
The C++ Standard Library
Introduction to the | Provides the ability to use:
C++ Standard Library. z String Types
z Data Structures (linked list, dynamic
arrays, priority queues, binary trees etc)
For : COP 3330. z Algorithms (Sorting and Searching…)
Object oriented Programming (Using C++)
z IO
http://www.compgeom.com/~piyush/teach/3330
z Classes for internationalization support.

Piyush Kumar

The C++ Standard Library C++ Standard Library

| Not very homogeneous: | Containers


z String classes are safe and convenient to z Objects that hold/contain other objects.
use (almost self explanatory). z Examples: vector, string
z The Standard Template Library (STL) | Algorithms
optimizes for performance and is not z Work on the containers
required to check for errors. To use it well, z Examples: sort, search
you need to understand the concepts and | Iterators
apply them carefully. z Provide pointer like interface to containers.

Other components Containers

| Allocators: Provide memory | Of course: Contain objects/built in


management for containers. Can be types.
customized. z More powerful than arrays.
| Adaptors: A mechanism to make one
z Grow (and shrink?) dynamically
thing act like another. Example: Stack.
z Manage their own memory
| Function objects: A function object
or a functor, is a construct allowing z Keep track of their size
an object to be invoked or called as if z Allow optimal algorithmic operations
it were an ordinary function, like scan, sorts etc.

COP 3330 Object Oriented Programming in C++ Lecture Slides 35/134 (c) pk
1
Containers Containers

| Standard STL sequence Containers: | Prefer sequential containers to arrays.


z vector, string, deque and list | Use vector by default
| Standard non-STL containers: | Use list when there are a lot of
z bitset, valarray, priority_queue, queue. 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? allocator


Vector Interface
template <class T, class Allocator = allocator<T> >
class vector {
data
size public:
...
explicit vector(const Allocator& = Allocator());
capacity explicit vector(size_type n, const T& value = T(),
const Allocator& = Allocator());
...
void reserve(size_type n);
...
| A contiguous array of elements data void resize(size_type sz, const T& c = T());
| The first “size” elements are constructed (initialized) ...
| The last “capacity - size” elements are uninitialized size void push_back(const T& x);
void pop_back();
| Four data members ...
z data pointer
capacity iterator insert(iterator position, const T& x);
void insert(iterator position, size_type n, const T& x);
z size allocator ...
z capacity or equivalent
iterator erase(iterator position);
z allocator iterator erase(iterator first, iterator last);
...
void clear();
Sample data layout: Internals. };

Vectors Containers : is empty?

| template <class T, class Allocator = | Always use:


allocator<T> > class vector { …}
z if(icontainer.empty()) …
| A default allocator is provided.
z Instead of if(icontainer.size() == 0)
| T is the type of the object stored in the
vector. | For some containers, calculating size
| Constructors for vector: takes linear time.
z vector<int> ivec1;
z vector<int> ivec2(3,9);
z vector<int> ivec3(ivec2);

COP 3330 Object Oriented Programming in C++ Lecture Slides 36/134 (c) pk
2
An example usage An example usage
#include <vector> #include <vector>
#include <iostream> #include <iostream>

using namespace std; using namespace std;


pk@linprog4:~>./a.out
int main() { int main() {
vec[0]=3
vector<int> vec(10); // Creates a vector
vec[1]=6 pk@linprog4:~>./a.out
vector<int> ivec;
vec[2]=7 Segmentation fault (core dumped)
// Initializes the vector cout << ivec[0]; //error
vec[3]=5
for(int i=0; i< vec.size(); i++) { vector<int> ivec2(10);
vec[4]=3
vec[i] = rand() % 10; // subscripts available: 0..9
vec[5]=5
cout << " vec[" << i << "]=" << vec[i] << endl; cout << ivec[10]; // error
vec[6]=6
};
vec[7]=2
return 0; return 0; Make this your friend…
vec[8]=9
} }
vec[9]=1

Iterators Iterators

| Browsers for containers. | A replacement for subscripting, for


| Allows restricted access to objects example in case of vectors: v[i]
stored in a container. | Subscripts are not available for all

| Can be a class, data structure or an containers but iterators are.


Abstract Data Type. | You can think of an iterator as
pointing to an item that is part of a
larger container of items.

Iterators Iterators
| Support the following operations:
| Container.begin() : All containers z Operator * : Element at the current position
support a function called begin, which (example: (*it)). You can use “->” to access
object members directly from the iterator.
will return an iterator pointing to the (Like a pointer)
beginning of the container (the first z Operator++ : Moves the iterator to the next
element) element. Most iterators will also allow you to
| Container.end() : returns an iterator use “ - - ” for stepping back one element.
corresponding to having reached the z Operator == and != : Compare two iterators
for whether they represent the same position
end of the container. (Not the last (not the same element).
element) z Operator = : Assigns an iterator.

COP 3330 Object Oriented Programming in C++ Lecture Slides 37/134 (c) pk
3
Iterators Iterators

| Vector iterator picture. | Defining an iterator:


std::class_name<template_parameters>::iterator name;
v.begin() v.end()
| Example:
std::vector<int>::iterator vit = myvec.begin();
data cout << (*vit) << endl;
| Printing all elements of a container.
| Reason for half-open range: std::container_type<template_parameter>::iterator pos;
for ( pos = container.begin();
z Easy looping pos != container.end(); ++pos)
z Empty containers Î begin() == end() cout << (*pos) << endl;

Iterators : Examples Iterators: Examples


using namespace std;
The non-STL way, using subscripts to access data: vector<int> myIntVector;
vector<int>::iterator myIntVectorIterator;
using namespace std; // Add some elements to myIntVector
myIntVector.push_back(1);
vector<int> myIntVector; myIntVector.push_back(4);
// Add some elements to myIntVector myIntVector.push_back(8);
myIntVector.push_back(1); //adds an element to end of vector.
myIntVector.push_back(4); for(myIntVectorIterator = myIntVector.begin();
myIntVector.push_back(8); myIntVectorIterator != myIntVector.end();
myIntVectorIterator++) {
for(int y=0; y<myIntVector.size(); y++) { cout<<*myIntVectorIterator<<" ";
cout<<myIntVector[y]<<" "; //Should output 1 4 8 // Should output 1 4 8
} }

Iterator Types Iterators

| Input Iterator : read only, forward moves. Type of iterator Example

| Output Iterator : write only, forward moves.


Input Iterator istream_iterator
| Forward Iterator: Both read/write with (++)
support
Output Iterator ostream_iterator, inserter,
| Backward: Both read/write with (--) support front_inserter, back inserter
| Bi-Directional :Read write and Both ++ or – Bi-directional iterator list, set, multiset, map,
Most support. multimap
Common
| Random: Read/Write/Random access. Random access iterator Vector, deque
(Almost act like pointers)

COP 3330 Object Oriented Programming in C++ Lecture Slides 38/134 (c) pk
4
Random Access Iterators Back to vectors
| Iterator type: Random-access
| Allow arithmetic | Operator [] overloaded
z it+n v.size() Number of elements in vector
z The result will be the element corresponding
v.Clear() Removes all elements
to the nth item after the item pointed to be
the current iterator. v.pop_back() Removes last element
z it – n also allowed v.push_back( elem ) Adds elem at end of vector
z (it1 – it2) allowed
• Example: Type of this operation for vectors is v.insert(pos,elem) Inserts elem at position pos and
returns the position of the new
defined by vector<T>::difference_type.
element.
v.erase(pos) Removes the element at the
Another form: iterator position pos and returns
v.erase(bpos,epos) the position of the next element.

Back to vectors Important facts


v.max_size() Maximum number of elements
possible (in entire memory!).
| For vectors, the C++ standard states:
v.capacity() Returns maximum number of
elements without reallocation z &v[i] = &v[0] + I
v.reserve(new_size) Increases capacity to new_size.
vector < char > vv;
vv.push_back ( 'P' );
vv.push_back ( 'Q' );
v.at( idx ) Returns the element with index
vv.push_back ( 'R' );
idx. Throws range error
vv.push_back ( '\0' );
exception if idx is out of range.
printf("%s\n",&vv[0]);
v.front() , v.back() Returns first , last element.
Output : PQR

v.resize(new_size) Changes the size to new_size.

The swap trick. Important Facts

| To trim capacity, you can use the | When deleting containers of


following trick: newed/malloced elements, remember
z std::vector<T>(v).swap(v); to delete/free them before deleting the
z Makes capacity = size. container.
• Example: vector<int>(ivec2).swap(ivec2); | Thread safety of STL containers:
z Multiple readers are ok
z Multiple writers to different containers
are ok.

COP 3330 Object Oriented Programming in C++ Lecture Slides 39/134 (c) pk
5
What can a container
Suggestions
contain?
| Minimal constraint on elements of a | Prefer vector and string to dynamically
container. allocated arrays.
z Operator= | Use reserve() to avoid unnecessary
• a = b; should be valid reallocations.
z A copy constructor | Avoid using vector<bool>
• YourType b(a); should be valid
| Question :
z Is vector<int&> allowed?

Understand Complexity
Algorithms
Example: Vector Insert
| Methods that act on containers (may or may What happens when the
not change them) vector is large?

z Examples: Sorting, searching, reversing etc.


z 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.

firstName[5] = ‘h’
Intro To The Standard string
Some string Functionality
firstName[6]
Class | Declaring a string:
is undefined unlike
C where its ‘\0’.
z string lastName;
| C++ has a standard class called "string" z string firstName(“Piyush”); //Note: String literal enclosed in double quotes
| Strings are simply a sequence of characters z string fullName;
z Note: This is not a sufficient definition for a "C-string" | Assigning a string:
z A "C-string" is an array of characters terminated by a z lastName = “Kumar”; //The usual assignment operator
null byte | Appending one string on the end of another:
| Must #include <string> using the standard namespace to z fullName = firstName + lastName; //Results in “PiyushKumar"
get C++ standard string functionality z fullName = firstName + " " + lastName; //Results in “Piyush Kumar"
z Note: This is different from #include'ing <string.h> | Accessing individual characters in a string:
which is the header required for "C-string"s z myChar = firstName[4]; //Results in ‘s' (no bounds checking)

| string variables are used to store names, words, phrases, z myChar = firstName.at(4); //Results in ‘s' (does bounds checking)
etc. | Appending a character to the end of a string:
| Can be input using ">>" and output using "<<" as other z lastName = lastName + myChar; //Results in “Kumars"
types | Determining number of characters in string:
z myInt = firstName.length(); //Results in 6

COP 3330 Object Oriented Programming in C++ Lecture Slides 40/134 (c) pk
6
string Example #1 Constructors
Length of Drew is: 4
Length of Morgan is: 6
Length of DrewMorgan is: 10
string() // empty string
#include <iostream>
#include <string>
using namespace std;
Length of Morgan is: 6 string(string s) // copy of s
Length of Drew Morgan is: 11
int main(void)
{ Length of Morgan is: 6 string(string s, int start) // substring start,end
string first;
string last("Morgan"); string(string s, int start, int len) // substring
first = "Drew"; //Would be illegal for C-string
cout << "Length of " << first << " is: " << first.length() << endl; string(char* a) // copy of C-string
cout << "Length of " << last << " is: " << last.length() << endl;

first += "Morgan";
string(int cnt, char c) // one or more chars
cout << "Length of " << first << " is: " << first.length() << endl;
cout << "Length of " << last << " is: " << last.length() << endl; string(char* beg, char* end) // [beg, end)
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);
}

Additional string
Other overloaded operators
Functionality
| Strings can be compared with usual operators | = is used to assign a value (char, C-string,
z >, >= (greater than, greater than/equal to) or string) to a string.
z <, <= (less than, less than/equal to) | += is used to append a string, character, or
z == (equality) C-string to a string.
| Strings also have a member function called "compare" | + is used to concatenate two strings or a
z int string::compare(string rhs); string with something else
z Return value is negative if calling string is less than rhs
| << and >> are used for input and output. On
z Return value is positive if calling string is greater than rhs
input, leading whitespace is skipped, and
z Return value is zero if both strings are identical
the input terminates with whitespace or end
of file.

When you need a C-string String Operations

string s = “1234”; s.append(s2); // append s2 to s


s.data() // returns s as a data array, no ‘\0’. s.push_back(c); // append a char
s.c_str() // returns s as a C-string with ‘\0’
s.erase(various); // erases substrings
int i = atoi(s.c_str()); // conversion
s.insert(various); // inserts substrings
// i is now 1234.
s.clear(); // removes all contents
char *carray = new char[80]; s.resize(cnt); // change the size of s to cnt
s.copy(carray, 79); // copies up to 79 char swap(a, b); // for general containers.

COP 3330 Object Oriented Programming in C++ Lecture Slides 41/134 (c) pk
7
String Operations string Example #2
s3 = "Drew";
if (s3 < s1)
int main(void)
cout << "oper: s3 less than s1";
{
if (s3 > s1)
s.replace(various); // replaces string s1 = "Drew";
string s3;
cout << "oper: s3 greater than s1";
if (s3 == s1)
characters int result;
cout << "oper: s3 is equal to s1";
cout << endl;
s3 = "Bob";
s.size(); or s.length(); // how many if (s3 < s1)
result = s3.compare(s1);
cout << "oper: s3 less than s1";
characters? if (s3 > s1)
if (result < 0)
cout << "comp: s3 less than s1";
cout << "oper: s3 greater than s1";
s.max_size(); // maximum number of if (s3 == s1)
cout << "oper: s3 is equal to s1";
else if (result < 0)
cout << "comp: s3 greater than s1";
char? cout << endl;
else
cout << "comp: s3 is equal to s1";
cout << endl;
s.empty(); // is s empty? result = s3.compare(s1);
if (result < 0)
return (0);
cout << "comp: s3 less than s1";
s.reserve(cnt); // reserves memory else if (result < 0)
}
cout << "comp: s3 greater than s1"; oper: s3 less than s1
else comp: s3 less than s1
cout << "comp: s3 is equal to s1";
cout << endl;
oper: s3 is equal to s1
comp: s3 is equal to s1

Even More string Functionality string Example #3


int main()
{ cout << "Spaces:";
int startPos; spaceLoc = myStr.find(" ");
| Getting a substring of a string: int len; while (spaceLoc != string::npos)
int commaLoc; {
z string string::substr(int startPos, int length)
int howLoc; cout << " " << spaceLoc;
• Returns the substring starting at "startPos" with length of "length" spaceLoc = myStr.find(" ", spaceLoc + 1);
int loc;
| Finding the location of a substring within a string: int spaceLoc; }
z int string::find(string lookFor); string myStr; cout << endl;
• Returns the index where the first instance of "lookFor" was found in the string string myStr2;
cout << "Punct and spaces:";
• Returns "string::npos" (which is usually -1) when the substring isn't found myStr = "Hello, how are you?"; loc = myStr.find_first_of(" ,?", 0);
z int string::find(string lookFor, int startFrom); startPos = 7; while (loc != string::npos)
• Returns the index where the first instance of "lookFor" was found, starting the search len = 3; {
cout << " " << loc;
at the index "startFrom", or "string::npos" when the substring isn't found myStr2 = myStr.substr(startPos, len);
cout << "Substr: " << myStr2 << endl; loc = myStr.find_first_of(" ,?", loc + 1);
| Finding specific characters in a string: }
commaLoc = myStr.find(",");
z int string::find_first_of(string charList, int startFrom); howLoc = myStr.find(myStr2); cout << endl;
• Returns the index of the first instance of any character in "charList", starting the searc cout << "Comma: " << commaLoc;
at the index "startFrom", or "string::npos" if none of the chars are found cout << " how: " << howLoc << endl; return (0);
}
z int string::find_first_not_of(string charList, int startFrom); Substr: how
• Returns the index of the first instance of any character NOT in "charList", starting the Comma: 5 how: 7
search at the index "startFrom", or "string::npos" if none of the chars are found Spaces: 6 10 14
Punct and spaces: 5 6 10 14 18

Some Final string


string Class Implementation
Functionality
| The string class uses dynamic memory allocation to be sure segmentation faults | Several member functions are available to get information about
don't occur a string
z When a string is updated such that it requires more characters than currently z capacity: The number of characters that can be placed in a
allocated, a new, larger array is allocated and the prior contents are copied over string without the inefficiency of re-allocating
as necessary z length: The number of characters currently in the string
| Since dynamic allocation is relatively slow, it is not desirable to be re-allocating | You can manually change the capacity of a string
strings often z resize: Sets the capacity of a string to be at least a user-
z C++ allows some memory to be "wasted" by often allocating more space than is defined size
really needed z This can be useful if you know a string will be at most n
z However, as strings are appended to the end, it is likely that a re-allocation won't characters long
be needed every time • By resizing the string to capacity n only that amount of
z Occasionally, re-allocation is necessary and is performed, again allocating more memory is associated with the string
memory than necessary • This prevents wasted memory when you know the exact
| Note: this is all done automatically by the string class ( Similar to vectors? ) 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
8
str += "-111-";
Example #4 cout << "Str: " << str << endl;
cout << "Length: " << str.length();
C Vs C++: Strings
int main(void) cout << " Cap: " << str.capacity();
{ cout << endl;
string str;
string str2; str += "1723-9"; C Library Functions C++ string operators
cout << "Str: " << str << endl;
cout << "Str: " << str << endl; cout << "Length: " << str.length(); /member functions.
cout << "Length: " << str.length(); cout << " Cap: " << str.capacity();
cout << " Cap: " << str.capacity(); cout << endl; strcpy =
cout << endl;

str = "888";
str += "abcdefghijklmnopqrstuv";
cout << "Str: " << str << endl;
strcat +=
cout << "Length: " << str.length();
cout << "Str: " << str << endl;
cout << "Length: " << str.length(); cout << " Cap: " << str.capacity(); strcmp = =, !=, <, >, <=, >=
cout << " Cap: " << str.capacity(); cout << endl;
cout << endl; strchr, strstr .find( ) method
return (0);
Str:
Length: 0 Cap: 0
} strrchr .rfind( ) method
Str: 888
Length: 3 Cap: 31 strlen .size( ) or .length( )
Str: 888-111-
Length: 8 Cap: 31
methods
Str: 888-111-1723-9
Length: 14 Cap: 31
Str: 888-111-1723-9abcdefghijklmnopqrstuv
Length: 36 Cap: 63

Reading text into a string Char functions in C/C++

getline(istream, s); // Reads from istream (e.g., | #include <ctype.h>


cin or a file) into the string s. Returns a | int isalnum(int c); //non-zero iff c is alphanumeric
| int isalpha(int c); //non-zero iff c is alphabetic
reference to istream that can be used again.
| int isdigit(int c); //non-zero iff c a digit: 0 to 9
| Reads all characters until a line delimiter or | int islower(int c); //non-zero iff c is lower case
end of file is encountered. | int ispunct(int c); //non-zero iff c is punctuation
| The line delimiter is extracted but not put
| int isspace(int c); //non-zero iff c is a space char
| int isupper(int c); // non-zero iff c is upper case
into the string
| int isxdigit(int c); //non-zero iff c is hexadecimal
| You can then parse s without worrying | int tolower(int c); //returns c in lower case
about end of line or end of file characters. | int toupper(int c); //returns c in upper case

Using the transform algorithm Using the transform algorithm


#include <algorithm> #include <algorithm>
| Lowercase all characters of a string: | What does the following do?
transform(s.begin(), s.end(), // source z If (s == reverse(s.begin(),s.end()))
s.begin(), // destination cout << “S is a …”;
tolower); // 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.

COP 3330 Object Oriented Programming in C++ Lecture Slides 43/134 (c) pk
9
Solution to assignment 1 Solution to assignment 1
sort(vs_inpvec.begin(), vs_inpvec.end());
vector<string> vs_inpvec; int i_inp_elements = vs_inpvec.size();
string s_one_entry; cout << "Input Elements = " << i_inp_elements << endl;
int counter = 0;
while( getline( cin, s_one_entry) ){ vs_inpvec.erase(
int _pos = s_one_entry.rfind('/'); unique(vs_inpvec.begin(), vs_inpvec.end()) ,
if(_pos != -1) vs_inpvec.end()
s_one_entry = s_one_entry.substr(_pos+1, s_one_entry.size() ); );

vs_inpvec.push_back(s_one_entry); int i_unique_elements = vs_inpvec.size();


} cout << "Unique Elements = " << i_unique_elements << endl;
cout << "Duplicate Elements = " <<
i_inp_elements - i_unique_elements
<< endl;

What does this code do? Reading assignment: Chapter 3, 9


Including Bitset.

#include <bitset> 00000000


10000011
bitset operators
| != returns true if the two bitsets are not equal.
| Ordered collection of bits.
| == returns true if the two bitsets are equal.
| Example program | &= performs the AND operation on the two bitsets.
| ^= performs the XOR operation on the two bitsets.
// create a bitset that is 8 bits long
bitset<8> bs; | |= performs the OR operation on the two bitsets.
// display that bitset | ~ reverses the bitset (same as calling flip())
for( int i = (int) bs.size()-1; i >= 0; i-- ) { cout << bs[i] << " "; } | <<= shifts the bitset to the left
cout << endl;
| >>= shifts the bitset to the right
// create a bitset out of a number bitset<8> | [x] returns a reference to the xth bit in the bitset.
bs2( (long) 131 ); // display that bitset, too
for( int i = (int) bs2.size()-1; i >= 0; i-- ) { cout << bs2[i] << " "; }
cout << endl;

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
10
Introduction To Pointers

Pointers and Arrays


| A pointer in C++ holds the value of a memory address
| A pointer's type is said to be a pointer to whatever type should be in the memory address it is
pointing to
z Just saying that a variable is a pointer is not enough information!
| Generic syntax for declaring a pointer:
dataType *pointerVarName;
| Specific examples
int *iPtr; //Declares a pointer called "iPtr" that will
For : COP 3330. //point to a memory location holding an
//integer value
Object oriented Programming (Using C++) float *fPtr; //Declares a pointer called "fPtr" that will
//contain an address, which is an address of
http://www.compgeom.com/~piyush/teach/3330
//a memory location containing a float value

Piyush Kumar

Using The "Address Of"


The Operator & 1000
Operator 1001

| There is an operator, &


1002 6 i
int i = 6; //Declares an int, stored 1003
z When this symbol is used as a unary operator on a variable it has a different
//in memory somewhere 1004
meaning than as a binary operator or type specifier
//In this example, it is
z It is unrelated to the "logical and", which is && or “bitwise and”, & 1005
z It is unrelated to the use of & in regards to reference parameters
//stored at address 1000
1006 1000 iPtr
| The operator & is usually called the "address of" operator int *iPtr; //Declares a pointer. The 1007
| It returns the memory address that the variable it operates on is stored at in memory //contents of this variable 1008
//will point to an integer 1009
| Since the result is an address, it can be assigned to a pointer
//value. The pointer itself
1010
//must be stored in memory, and
//in this example, is stored at 1011
//memory location 1004

iPtr = &i; //Sets the iPtr variable to


//contain the address of the
//variable i in memory

Using The Dereference


The Operator * 1000

Operator 1001
1002 6 4 i
| Like the &, the * operator has another meaning as well 1003
| The * operator is usually referred to as the "dereference operator" int i = 6; //Declares integer called i 1004
| The * operator operates on a pointer value int *iPtr; //Declares a pointer to an int
1005
z The meaning is "Use the value that this pointer points to, rather than the
iPtr = &i; //Sets the iPtr variable to 1006 1000 iPtr
value contained in the pointer itself"
//contain the "address of" the 1007
| If a pointer is of type "int *" and the dereference operator operated on the //variable i in memory 1008
pointer, the result is a value of type "int"
1009
| Dereferenced pointers can be used as L-values or R-values cout << "i: " << i << endl;
1010
z When used as an L-value (on the left side of an assignment), the pointer cout << "i: " << *iPtr << endl;
is unaffected, but the memory that it points to is changed 1011
| When a pointer that is pointing to memory you are not allowed to access is *iPtr = 4; //Changes the memory being
dereferenced, the result is a program crash via a "segmentation fault" //pointed to by iPtr to contain
i: 6
//the value 4 i: 6
i: 4
cout << "i: " << i << endl; i: 4
cout << "i: " << *iPtr << endl;

COP 3330 Object Oriented Programming in C++ Lecture Slides 45/134 (c) pk
1
Arrays And Pointers Pointer Arithmetic,
| The name of an array variable in C++, without the use of the [ ] operator, represents Motivation
the starting address of the array
| Incrementing the contents of an "int
| This address can be stored in a pointer variable *" variable by one doesn't make
z Since array values are guaranteed to be in contiguous memory, you can access sense 1000 NUM 1012 iAry[2]
array values using this one pointer z Integers require 4 bytes of
3 6
1001 1013
z Examples of this will come later, after discussing "pointer arithmetic" storage 1002 1014

const int NUM = 3; z Incrementing iPtr by 1, results in 1003 1015

int iAry[NUM] = { 2, 4, 6 }; the pointer pointing to location 1004 iAry[0] 1016 iPtr

int *iPtr; 1000 NUM 1012 iAry[2] 1005 1005


1006 2
1017
1018
1004
z However, location 1005 is not
3 6
1001 1013
iPtr = iAry; //Assigns iPtr to point 1002 1014 an address that is the starting
1007 1019

//to the first integer 1003 1015 address of an integer


1008 iAry[1] 1020

//in the iAry array 1004 iAry[0] 1016 iPtr


| Dereferencing a pointer that
1009
1010 4 1021
1022

//This cout prints the value of the


1005
1006 2
1017
1018
1004 contains an invalid memory location,
such as 1005 may result in a Bus
1011 1023

//value stored in the location iPtr 1007 1019


Error
//points to (the first int in the 1008 iAry[1] 1020
//iAry, in this case) z When your program results in a
cout << "val: " << *iPtr << endl;
1009
1010 4 1021
1022
bus error, the program crashes
immediately (Segmentation
1011 1023
val: 2 fault).

Pointer Arithmetic,
Using Pointer Arithmetic
Description 1000 NUM 1012 iAry[2]

3 6
1001 1013
| Recall that a pointer type specifies the type of value it is pointing to const int NUM = 3;
1002 1014
int iAry[NUM] = { 2, 4, 6 };
z C++ can determine the size of the value being pointed to int *iPtr; 1003 1015
int *iPtr2; 1004 iAry[0] 1016 iPtr
z When arithmetic is performed on a pointer, it is done using this knowledge to
int *iPtr3;
ensure the pointer doesn't point to intermediate memory locations int i;
1005
1006 2
1017
1018
1004
z If an int requires 4 bytes, and iPtr is a variable of type "int *", then the statement 1007 1019
iPtr = iAry; //Assigns iPtr to point
"iPtr++;" actually increments the pointer value by 4 //to the first integer
1008 iAry[1] 1020

z Similarly, "iPtr2 = iPtr + 5;" stores the address "five integers worth" past iPtr in
iPtr2
//in the iAry array 1009
1010 4 1021
1022
iPtr3 = iAry; 1011 1023
• If iPtr was 1000, then iPtr2 would contain the address 1020 for (i = 0; i < NUM; i++)
{
• 1020 = 1000 + 5 * 4 iPtr2 = iPtr + i;
| Pointer arithmetic is performed automatically when arithmetic is done on pointers cout << i << " " << 02222
iAry[i] << " " <<
z No special syntax is required to get this behavior! *iPtr2 << " " << 14444 Other
*iPtr3 << " " << 26666 Variables
*(iPtr + i) << endl;
iPtr3++;
}

Dynamic Allocation Of
Static Allocation Of Arrays
| All arrays discussed or used thus far in the course have been "statically allocated"
Arrays
z The array size was specified using a constant or literal in the code
| If an array is "dynamically allocated", then space is not reserved
z When the array comes into scope, the entire size of the array can be allocated,
for the array until the size is determined
because it was specified
z This may not be until the middle of a function body, using a
| You won't always know the array sizes when writing source code value that is not constant or literal
z Consider a program that modifies an image
z The size may be input by the user, read from a file,
z As the developer, you won't know what image size the user will use computed from other variables, etc.
z One solution: Declare the image array to be 5000 rows by 5000 columns | As memory is "claimed" using dynamic allocation, the starting
• Problem #1: This likely wastes a lot of memory – if the user uses an image address is provided, allowing it to be stored in a pointer variable
that is 250x250, then there are 24,937,500 unused pixels. If each pixel | Since pointers can be used to access array elements, arrays
requires 4 bytes, this is almost 100 MB (megabytes!) of wasted space can be dynamically allocated in this way
• Problem #2: What if the user needs to edit an image that is 6000x6000? | Dynamically allocated memory is claimed from the heap, as
Your program will fail, and likely result in a crash opposed to the stack

COP 3330 Object Oriented Programming in C++ Lecture Slides 46/134 (c) pk
2
The "new" Operator Static Vs Dynamic Allocation
| A new operator is used to perform dynamic allocation
Stack allocation
z The operator is the "new" operator
| The new operator: int intArray[10];
z Attempts to find the amount of space requested from the heap intArray[0] = 6837; Code
z "Claims" the memory when an appropriately sized available chunk of the heap is
found Heap allocation Stack
z Returns the address of the chunk that was claimed
int *intArray;
| "new" can be used to allocated individual variables: intArray = new int[10];
iPtr = new int; //allocates an int variable intArray[0] = 6837;
| "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
Heap
the well-know [ ] operator, indexing an array delete[] intArray;

Dynamic Allocation Of Outputs Of Dynamic


Arrays, Example Allocation Example
| This fragment lets the user decide how big of an array is needed
Enter length of array: 7 Enter length of array: 3
int i; //Loop variable Enter int num 0:3 Enter int num 0:8
int *iary; //This will be our array - an int pointer Enter int num 1:4
int num; //Length of the array (input from user)
Enter int num 1:1
Enter int num 2:6 Enter int num 2:1
cout << "Enter length of array: "; Enter int num 3:8 Index 0: 8
cin >> num; Enter int num 4:3 Index 1: 4
iary = new int[num]; //Dynamically declare an ary. Get Index 2: 1
//necessary mem, assign address to iary
Enter int num 5:2
for (i = 0; i < num; i++) Enter int num 6:1 Note: In the left example, the array required 28
{ Index 0: 3 bytes of memory (7 * 4). Exactly 28 bytes was
cout << "Enter int num " << i << ":"; Index 1: 1 allocated for the array.
cin >> iary[i]; //use iary as if it were an array!
}
Index 2: 6
Index 3: 8 In the right example, the array required only 12
for (i = 0; i < num; i++) Index 4: 3 bytes (3 * 4). Exactly 12 bytes was allocated for
{ Index 5: 2 the array, and no extra memory was unused and
cout << "Index " << i << ": " << iary[i] << endl;
Index 6: 1 wasted.
}

Another Dynamic Allocation Example Problem


Example Description
| The likely result would be that the program would be a failure
| What is the likely result of the z The reason is that the new operator claims the memory requested each
following program fragment? iteration of the loop
z There is only a finite amount of memory, though, and the amount
int i; //Loop variable requested is likely beyond the amount available
int *iary; //This will be our array - an int pointer
int num; //Length of the array (input from user)
| The problem is that while the memory is claimed, it is never released, of
"freed", or "deleted"
for (i = 0; i < 100000; i++) | If you don't free the memory, but you do change the pointer pointing at it to
{ point to a different address, then:
num = 50000; z The original memory is still claimed
z There is no way to access the original memory, since no pointers are
iary = new int[num]; pointing to it
z The chunk of memory is wasted throughout the entire execution of the
//Call a function to randomly fill the array
program
//Do some sort of processing on the 50000 element ary
//Do it again and again and again, accumulating stats. z This is referred to as a "memory leak", and should be avoided
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 47/134 (c) pk
3
Using The "delete" Operator Fixing The Memory Leak
| Dynamically allocated memory can be released back into the available memory store
using the "delete" operator int i; //Loop variable
int *iary; //This will be our array - an int pointer
| The delete operator operates on a pointer and frees the memory being pointed to int num; //Length of the array (input from user)
z Recall – a pointer may be pointing to a single value, or an array of values
for (i = 0; i < 100000; i++)
z Due to this, the delete operator is used differently to delete single values and
{
arrays num = 50000;
| Deleting a single value being pointed to:
delete iPtr; iary = new int[num];
| Deleting an array of values being pointed to: //Call a function to randomly fill the array
delete [] iPtr; //Do some sort of processing on the 50000 element ary
| Using the delete operator on a null pointer has no effect //Do it again and again and again, accumulating stats.
| Using the delete operator on a pointer pointing to memory that is not currently delete [] iary; //No need to tell delete the size of
claimed by your program will cause a segmentation fault //the array. This only frees up the
z Initialize all pointers to 0 (zero) //memory that iary is pointing to. It
//does NOT delete the pointer in any way
z Set all pointers to 0 after using the delete operator on them
}

Dynamically Allocating Using The Arrow Operator


Objects ->
class CircleClass
| The arrow operator is another operator needed for working with {
pointers public:
float x;
z The arrow operator is a dash and a greater than symbol: ->
float y;
z It is used to access public member variables or functions of float z;
an object that is being pointed to by a pointer float radius;
I access the same memory location using
}; both the actual object and a pointer to that
z It is used the same way the dot operator is used on an
actual object, but the arrow is used on a pointer variable
object.
int main()
instead {
| The arrow is used for convenience CircleClass myObj;
The dot operator is used with the object
z Alternatively, you could deference the pointer and use the CircleClass *myPtr;
dot operator
myPtr = &myObj; The arrow operator is used with the pointer
| Since the arrow operator implies a dereference, using the arrow myObj.x = 5;
operator on a pointer that doesn't point to claimed memory myPtr->y = 9;
results in a segmentation fault! myObj.z = 15;
myPtr->radius = 56.4;

...

Dynamically Allocating Using Constructors With


Objects Dynamic Allocation
| Remember – a constructor is used whenever an object is allocated, whether
class TempClass Note: The actual object that is statically or dynamically
{ allocated (the memory location)
public: never gets a name! It is only pointed class IntClass
{
int ival; to by the temp pointer! public:
double dval; int val;
};
IntClass() //Default ctor sets val to 0
{
int main() val = 0;
{ }
TempClass *temp; //4 bytes (or sizeof(tempClass*) IntClass(int inVal) //Initializes val to value passed in
{
temp = new TempClass; //Claims enough space for all val = inVal;
//members of a tempClass object }
};
temp->ival = 16; //Since temp is a pointer, IntClass ic; //sets ic.val to 0 Uses the
temp->dval = 4.5; //the arrow operator is used IntClass *icPtr = new IntClass; //sets icPtr->val to 0 default ctor

... IntClass ic2(6); //sets ic2.val = 6 Uses the


IntClass *icPtr2 = new IntClass(10); //sets icPtr->val to 10 value ctor

COP 3330 Object Oriented Programming in C++ Lecture Slides 48/134 (c) pk
4
The sizeof Operator Dynamically Alloc Mem in C
| Often, you need to know how many bytes of memory a variable or type requires.
| Operators "new" and "delete" don't exist in C, but C programmers still need dynamic
| Different architectures use different sizes. allocation.
| Use the sizeof operator to determine the current architecture's size of a var or type | Three important functions for C dynamic allocation

//malloc takes one parameter, size, which is simply


int num; //Length of the array (input from user)
cout << "sizeof(int): " << sizeof(int) << endl;
//the number of bytes you are requesting.. Returns a
cout << "sizeof(float): " << sizeof(float) << endl; //void *, which is a generic pointer to any type.
cout << "sizeof(double): " << sizeof(double) << endl; void *malloc(size_t size);
cout << "sizeof(char): " << sizeof(char) << endl;
cout << "sizeof(num): " << sizeof(num) << endl; //calloc initializes each ary element to 0. nelem is
//the number of elements you are requesting, and
sizeof(int): 4
//elsize is the number of bytes each element requires.
sizeof(float): 4
Result may vary on void *calloc(size_t nelem, size_t elsize);
sizeof(double): 8
sizeof(char): 1
different machines!
sizeof(num): 4 (These results are common) //free takes one param, which is a pointer to memory
//that was previously allocated using malloc or calloc
void free(void *ptr);

Dynamically Alloc Mem in C


Prefer C++ to C
Example
#include <stdlib.h> string *stringarray1 = static_cast<string *> (malloc(10*sizeof(sting)) );
//--- string *stringarray2 = new string[10];
int *iary; //This will be our array - an int pointer
int *iary2; //Another integer array. …
int num; //Length of the array (input from user)
free (stringarray1); // no destructors called
cout << "Enter length of ary: "; // What happened if string object reallocated stuff? Enlarged itself?
cin >> num; delete[] stringarray2;

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);

Use same form of new/delete in


new/delete constructors/destructors
string *stringarray2 = new string[100];
| For a class with dynamically allocated
… memory, Initialize pointers in
delete stringarray2; constructors to 0.
// Program behavior undefined
// At least the 99 strings are still in the memory somewhere Æ Memory LEAK! | If unknown size, make them null.
z 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
5
Out of memory errors Multidimensional Arrays
#include <iostream>

using namespace std; | Definition


Type MDarray[size_1][size_2] ... [size_k]
void OutOfMemory(){
| What it means
cerr << "No more memory\n";
abort(); z k - dimensional array
} z MDarray: array identifier
z size_i: a positive constant expression
z Type: standard type or a previously defined user
int main() { type and is the base type of the array elements
set_new_handler(OutOfMemory);
double *pbigarray = new double[200000000]; | Semantics
cout << "I am here\n"; z MDarray is an object whose elements are indexed by
pbigarray[9999999] = 123; a sequence of k subscripts
cout << pbigarray[999999] << endl;
z the i-th subscript is in the range 0 ... size_i-1

return 0;
}

Multi-dimensional Arrays Multi-dimensional Arrays

| Multidimensional arrays are laid out in


row-major order
| Consider
int M[2][4];
| M is two-dimensional array that
consists of 2 subarrays each with 4
elements.
z 2 rows of 4 elements

| The array is assigned to a contiguous


section of memory
z The first row occupies the first portion
z The second row occupies the second
portion

© Art of Assemby website.

Multi-dimensional arrays Multi-dimensional arrays


00 01 02 03
| Example: | Really an array of 10 11 12 13
arrays.
int myImage[NROWS][NCOLS]; 20 21 22 23
Can be used as parameter in a int main() {
int x [3][4];
function prototype. Example: int (*ip)[4]; // pointer to an array of 4 integers
int *oip = &(x[0][0]);
void process_matrix( int in[ ][4], int out[ ][4], int nrows) ip = x;
void process_matrix( int in[4][4], int out[4][4], int nrows) for (int i = 0 ; i < 3; ++i)
for (int j = 0; j < 4; ++j)
x[i][j] = i*10 + j;
//Invalid cout << (*ip)[0] << "\t" << (* (++ip) )[0] << endl;
void process_matrix( int in[][], int out[][], int nrows) cout << * (++oip) << endl;
return 0;
}
Recommended exercises: 5.9, 5.30, 5.14, 5.23

COP 3330 Object Oriented Programming in C++ Lecture Slides 50/134 (c) pk
6
Multi-dimensional Arrays Buffer Overflow problems
Let A be a string and B be an integer. A A A A A A A A B B
| int (*matrix)[10]; Changing A could change B!
0 0 0 0 0 0 0 0 0 3
z Pointer to an array of 10 integers
/* overflow.c - demonstrates a buffer overflow */
| int *matrix[10]; #include <stdio.h>
#include <string.h>
z Array of 10 integer pointers. int main(int argc, char *argv[]) {
char buffer[10];
z Example: if (argc < 2) {
• int main( int argc , char *argv[]) fprintf(stderr, "USAGE: %s string\n", argv[0]);
return 1;
• argv[0] = “prgram name” }
• argv[1] = “../data/filename”
• argv[2] = “2” strcpy(buffer, argv[1]);
return 0;
}

Buffer Overflow problems Type conversions


Let A be a string and B be an integer. A A A A A A A A B B
| C-Style casts
Changing A could change B!
0 0 0 0 0 0 0 0 0 3 z float average = (float) sum /
/* better.c - demonstrates one method of fixing the problem */ items;
#include <stdio.h>
z float average = (float)
#include <string.h>
(sum/items);
int main(int argc, char *argv[]) { | C++ Style
char buffer[10];
if (argc < 2) { z static_cast< type >( identifier )
fprintf(stderr, "USAGE: %s string\n", argv[0]); z float average = static_cast< float >( sum ) /
return 1; items;
} z float average = sum / static_cast< float >(
items );
strncpy(buffer, argv[1], sizeof(buffer));
buffer[sizeof(buffer) - 1] = '\0';
return 0;
}

Type conversions static_cast

| static_cast<T>(expression)
x=(float) i; cast in C++ - C notation
The static_cast<>() is used to cast between the
x=float(i); cast in C++, functional notation integer types.
'eg' char->long, int->short etc.
x=static_cast<float>(i); ANSI C++ - recommended
| Static cast is also used to cast pointers to
i=reinterpret_cast<int>(&x) ANSI C++, not portable and system related types, for example casting void* to the
dependent
func(const_cast<int>(c_var)) where C_var is a const variable
appropriate type.
Used for removing “const-ness” when
invoking func. Use with care. 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
7
reinterpret_cast const_cast

float f = 2.5f;
| const_cast<T>(expression)
double * pd = reinterpret_cast<double*>(&f); The const_cast<>() is used to
cout << f << endl << *pd << endl; add/remove const(ness) of a variable.
Outputs (!!!):
class A {public: void func() {} };
$ ./a.exe void f(const A& a)
2.5 {
3.50861e+159 A& b = const_cast<A&>(a);
b.func();
}
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.

dynamic_cast Type conversions


| Dynamic cast is used to convert pointers and references | All Pointers can be converted to void *
at run-time, generally for the purpose of casting cast a
pointer or reference up or down an inheritance chain | An explicit cast is required in C++
(inheritance hierachy).
when you want to convert a void * to
class Employee { ... };
another pointer type.
class Manager : public Employee { ... };
char *char_p;
void f(Employee* a) { void *generic_p;
Manager* b = dynamic_cast<Manager*>(a); ...
} 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 int
| Integer types which cannot be
represented with an int are promoted to
unsigned
| In 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
8
GDB

GDB |

|
Lot of tutorials on google.
Debugging tool, see what happens as your
program runs
| Needs the –g flag while compiling
For : COP 3330. z This adds additional information (i.e. line
Object oriented Programming (Using C++) numbers) in the binary executable
http://www.compgeom.com/~piyush/teach/3330 | Execution:
z Invoke by typing “gdb <executable name>”
z E.g.: gdb a.out

Piyush Kumar

Basic Commands Basic Commands


| continue
| quit z Resume execution
z Quits gdb. Note that it is NOT exit… | step (s)
| run z Step to the next line in CODE.
z Run the program; it stops at each break point set by z Warning: If you use the step command while control is within a function that
break command was compiled without debugging information, execution proceeds until control
reaches a function that does have debugging information.
| x (address) | next (n)
z Examine the CONTENTS of the memory at (address)
z Similar to step
| print (expression) z This is similar to step, but function calls that appear within
z Print the value of the expression - can be registers or the line of code are executed without stopping.
simple equations
| disas
| break (function name or *memory address)
z Show assembly instructions for the current function
z Set breakpoints
z E.g. : break main
z break x.cpp:15

Basic Commands
| where/bt
z Shows the current line and stack backtrace. Very
useful for segmentation faults.
| info registers
z Shows the current state of the registers
| display <var/register>
z display the contents of the register/var.
z E.g. : display count
z display $eax
| More Commands:
z http://sources.redhat.com/gdb/onlinedocs/gdb_toc.html
| Graphical User interface: ddd
| Screen shots/movies : http://undo-software.com/undodb_screens.html

COP 3330 Object Oriented Programming in C++ Lecture Slides 53/134 (c) pk
1
Exceptions
Exceptions are run‐time anomalies, such as division by 
Exceptions

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. 
For : COP 3330. • Useful when the code that detects the problem cannot 
Object oriented Programming (Using C++) handle it (Exception‐Detection code). Control must be 
transferred to the code that can handle such error. 
http://www.compgeom.com/~piyush/teach/3330 (Exception‐Handling code).

Piyush Kumar
Material from “4th ed. Programming and Problem solving with C++, Dale, Weems.

Exceptions in C++ Exceptions in C++


• Communication between exception‐detection  • If not handled properly, exceptions can cause the program
and exception‐handling parts of the program  to :
in C++. It involves: • Crash
• throw expressions • Falls into unknown state
• try blocks • An exception handler is a section of program code that is
designed to execute when a particular exception occurs
• exception classes
• Resolve the exception
• The try, throw, and catch statements 
• Lead to known state, such as exiting the program
implement exception handling. 

Standard Exceptions The throw Statement


Throw: to signal the fact that an exception has
| Exceptions Thrown by occurred; also called raise
z the Language
• new Syntax
z Standard Library Routines
throw  Expression
z User code, using throw statement

COP 3330 Object Oriented Programming in C++ Lecture Slides 54/134 (c) pk
1
The try-catch Statement Example of a try-catch Statement
How one part of the program catches and processes try
{
the exception that another part of the program throws. // Statements that process personnel data and may throw
TryCatchStatement // exceptions of type int, string, and SalaryError
}
try catch ( int )
Block {
// Statements to handle an int exception
catch (FormalParameter) }
Block catch ( string s )
catch (FormalParameter) {
cout << s << endl; // Prints "Invalid customer age"
FormalParameter // More statements to handle an age error
}
DataType VariableName catch ( SalaryError )
{
// Statements to handle a salary error
… }

Execution of try-catch Throwing an Exception to be


Caught by the Calling Code
A No
statement throws statements throw void Func3()
an exception an exception {

Control moves Exception try


directly to exception { void Func4()
handler
Handler Function
{
call
Func4();
Normal if ( error )
} return throw ErrType();
Statements to deal with exception are executed catch ( ErrType )
{ }
}
Statement Return from
} thrown
following entire try-catch
statement exception

Practice: Dividing by ZERO A Solution


Apply what you know:
int Quotient(int numer, // The numerator
int Quotient(int numer, // The numerator
int denom ) // The denominator
int denom ) // The denominator
{
{
if (denom == 0)
if (denom != 0) throw DivByZero();
return numer / denom; //throw exception of class DivByZero
else return numer / denom;
//What to do?? do sth. to avoid program }
//crash
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 55/134 (c) pk
2
A Solution cin >> numer >> denom;
while (cin)
{
//“quotient.cpp” -- Quotient program try
#include<iostream> {
#include <string> cout << "Their quotient: "
<< Quotient(numer, denom) << endl;
using namespace std;
}
int Quotient(int,int);
catch (DivByZero)
class DivByZero // Exception class
{
{}; cout << "*** Denominator can't be 0"
int main() << endl;
{ }

int numer; // Numerator cout << "Enter numerator and denominator: ";

int denom; // Denominator cin >> numer >> denom;


}
cout << "Enter numerator and denominator: "; return 0;
}

int Quotient(/*in */int numer, // The numerator


/*in */int denom) // The denominator
{
if(denom == 0)
throw DivByZero();
return numer / denom;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 56/134 (c) pk
3
Functions in C++
Declarations vs Definitions 
Functions |

| Inline Functions
| Class Member functions
| Overloaded Functions
For : COP 3330.
| Pointers to functions
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
| Recursive functions

Piyush Kumar

Gcd Example
1071,1029
What you should know? 1029, 42
42, 21
Calling a function?
21, 0 #include <iostream>

| Defining a function Non-reference parameter.


using std::cout;
using std::endl;
using std::cin;
// return the greatest common divisor
int gcd(int v1, int v2) int main()
{ {
while (v2) { // get values from standard input
int temp = v2; cout << "Enter two values: \n";
Function body Another scope.
v2 = v1 % v2; int i, j;
is a scope temp is a local variable
v1 = temp; cin >> i >> j;
}
return v1; // call gcd on arguments i and j
} // and print their greatest common divisor
cout << "gcd: " << gcd(i, j) << endl;
function gcd(a, b) return 0;
if b = 0 return a }
else return gcd(b, a mod b)

Function return types Parameter Type-Checking

// missing return type gcd(“hello”, “world”);


Test(double v1, double v2){ /* … */ } gcd(24312);
gcd(42,10,0);
int *foo_bar(void){ /* … */ }
gcd(3.14, 6.29); // ok?
void process ( void ) { /* … */ }
// Statically typed language
int manip(int v1, v2) { /* … */ } // error

int manip(int v1, int v2) { /* … */ } // ok

COP 3330 Object Oriented Programming in C++ Lecture Slides 57/134 (c) pk
1
Pointer Parameters Const parameters
#include <iostream>
#include <vector>
using std::vector; | Fcn(const int i) {}…
using std::endl;
using std::cout;
z Fcn can read but not write to i.
void reset(int *ip)
{
*ip = 0; // changes the value of the object to which ip points
ip = 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: 42


reset(p); // changes *p but not p
cout << "i: " << *p << endl; // ok: prints i: 0
return 0;
}

Reference Parameters Passing Iterators


// vec is potentially large, so copying vec might be expensive
// use a const reference to avoid the copy
void print(const vector<int> &vec) // pass iterators to the first and one past the last element to print
void print(vector<int>::const_iterator beg,
{
vector<int>::const_iterator end)
for (vector<int>::const_iterator it = vec.begin(); {
it != vec.end(); ++it) { while (beg != end) {
if (it != vec.begin()) cout << " "; cout << *beg++;
cout << *it; if (beg != end) cout << " "; // no space after last element
} }
cout << endl; cout << endl;
Can be used to }
} return information
int main()
{
vector<int> vec(42);
print(vec.begin(), vec.end()); // Defined on next slide
print(vec);
}

Const references Passing reference to a pointer

// swap values of two pointers to int


// When you don’t what the function to modify the value associated with void ptrswap(int *&v1, int *&v2)
// the reference {
int *tmp = v2;
bool isShorter(const string &s1, const string &s2){ v2 = v1;
return s1.size() < s2.size(); 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
2
Array parameters No return values?

| void printvalues(const int ia[10]); | void swap (int &v1, int &v2);
z Parameter treated as “const int *”

Returning from main Returning a reference


#include <string>
using std::string;
#include <cstdlib> #include <iostream>
int main() using std::cout; using std::endl; Tip 1: Never return a reference
{
to a local object.
bool some_failure = false; //inline version: find longer of two strings
if (some_failure) inline const string &
shorterString(const string &s1, const string &s2) Tip 2: Never return a pointer
return EXIT_FAILURE;
{ to a local object.
else
return s1.size() < s2.size() ? s1 : s2;
return EXIT_SUCCESS;
}
}
int main()
{
string s1("successes"), s2("failure"); Put these in header
cout << shorterString(s1, s2) << endl; files.

return 0;
}

Recursion Recursion

| Recursion is the process a procedure function factorial(n) {


if (n <= 1) return 1;
goes through when one of the steps of else return n * factorial(n-1);
the procedure involves rerunning the }

entire same procedure.

| Fibonacci number sequence:


z F(n) = F(n − 1) + F(n − 2).

COP 3330 Object Oriented Programming in C++ Lecture Slides 59/134 (c) pk
3
Recursion Recursion
int main() {
template <typename T> vector<int> vs;
void recSort(T begin, T end){ int N = 10;
int len = distance(begin,end);
if( len <= 1) return; for(int i = 0; i < N; ++i)
vs.push_back(rand());
for(int i = 1; i < len; ++i)
if(*(begin+i) < *(begin)) recSort(vs.begin(), vs.end());
swap( *(begin+i) , *(begin) ); for(int i = 0; i < N; ++i)
recSort(begin+1,end); cout << vs[i] << endl;
return 0;
} }

Recursion Recursion
void recSort(vector<int>::iterator begin,
template <typename T>
void recSort(T begin, T end){
vector<int>::iterator end){
int len = distance(begin,end);
| Another example.
int len = distance(begin,end);
if( len <= 1) return; void printNum(int n)
if( len <= 1) return; Generates {
for(int i = 1; i < len; ++i) for(int i = 1; i < len; ++i) if (n >= 10) printNum(n/10);
if(*(begin+i) < *(begin)) if(*(begin+i) < *(begin)) print(n%10);
swap( *(begin+i) , *(begin) ); }
swap( *(begin+i) , *(begin) );
recSort(begin+1,end);
recSort(begin+1,end); Another version.
}
}
void printNumB(int n, int b)
{
if (n >= b) printNumB(n/b);
print(n%b);
Can you see the recursion in a Sudoku solver? }

Recursion Recursion
Eight Queens problem:
|
z Brute force solution: 64^8 = 2^48 = 281,474,976,710,656 possible
| Invariants:
blind placements of eight queens,
z no two pieces can share the same row
z any solution for n queens on an n×m
board must contain a solution for n−1
queens on an (n−1)×m board
z proceeding in this way will always
keep the queens in order, and
z The eight queens puzzle is based on the problem of
generate each solution only once.
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.

COP 3330 Object Oriented Programming in C++ Lecture Slides 60/134 (c) pk
4
Backtracking Eight Queens

| A strategy for guessing at a solution | An observation that eliminates many


and backing up when an impasse is arrangements from consideration
reached z No queen can reside in a row or a
| Recursion and Backtracking can be column that contains another queen
used together to solve our problem • Now: only 40,320 (8!) arrangements of
queens to be checked for attacks along
(and many other problems)
diagonals

Eight Queens The Eight Queens Problem

| A recursive algorithm that places a queen in


a column
z Base case
• If there are no more columns to consider
• You are finished
z Recursive step
• If you successfully place a queen in the current
column
• Consider the next column
Figure 5.1 a) Five queens that cannot attack each other, but that can attack all of column 6; b) backtracking to
• If you cannot place a queen in the current column
column 5 to try another square for the queen; c) backtracking to column 4 to try another square for the queen and
• You need to backtrack
then considering column 5 again

Default Arguments Static variables.

int ff(int i = 0); | Retain their values across function


screen = screenInit( string::size_type height = 24,
string::size_type width = 80,
calls.
char background = ‘ ‘ ); | In this course you are barred from

string screen = screenInit();


using them.
string screen = screenInit(66);
string screen = screenInit(66,256);
string screen = screenInit(66,256,’#’);
string screen = screenInit(,,’?’); // error
string screen = screenInit(’?’); // calls (‘?’,80,’ ‘);

You can also call functions to initialize default


Arguments. These functions are called when the function is called.

COP 3330 Object Oriented Programming in C++ Lecture Slides 61/134 (c) pk
5
Function overloading

| Functions having same name but


different parameter types.
z Record lookup(const Account&);
z Record lookup(const Phone&);
z Record lookup(const Name&);
z Record lookup(const SS&);

COP 3330 Object Oriented Programming in C++ Lecture Slides 62/134 (c) pk
6
Classes: Member functions
// classes example
#include <iostream>
Classes: Methods, Constructors, using namespace std;

Destructors and Assignment class Square {


int x;
public:
int area () {return (x*x);};
void set_values(int a);
For : COP 3330. int get_sidelen(void) const;
};
Object oriented Programming (Using C++) void Square::set_values(int a){ x = a; };
http://www.compgeom.com/~piyush/teach/3330 int Square::get_sidelen(void) const { return x;}

int main () {
Square s;
s.set_values (3);
cout << "area: " << s.area();
Piyush Kumar return 0;
}

Member functions: Methods Objects : Reminder

| private members of a class are accessible | An object is an instance of a class.


only from within other members of the same
| Memory is allocated for each object
class or from their friends.
instantiated (and not for the class).
| protected members are accessible from
members of their same class and from their z Example:
friends, but also from members of their • Square S; // S is an object of Square class. (on stack)
derived classes. • Square *pS = new Square; // on heap.
| Finally, public members are accessible from | An object of a class can be defined in
anywhere where the object is visible. the same way as an internal type.

Objects : Reminder Objects: Reminder

| Multiple objects of a class can be | The data members and member


created (as many as you want). functions of an object have the same
| All the objects share the same copy of properties as the data members and
member functions. member functions of its class.
| But, they maintain a separate copy of
data members.
z Square s1,s2; // each has separate copy of x

COP 3330 Object Oriented Programming in C++ Lecture Slides 63/134 (c) pk
1
Assignment operator Variable assignment

| Square s3 = s2; | Values are assigned to variables and


| By default, copying a class object is not to their data types.
equivalent to copying all its elements | Hence, you assign values to members
including pointers. of an object and not a class.
| Must create a unique object of a class
because you cannot assign values to
a class.
z Square = 5 is meaningless…

Back to member functions Member functions

| The member functions in the public | Only the public members of an object
section of a class can be accessed can be directly accessed.
using the “.” operator for instantiated
objects. (For pointers its -> )
z Square s1, *s2;
z s1.set_values(5);
z s2 = new Square; s2->set_values(10);
z delete s2;

Special Member functions Constructors & Destructors

| Constructors: Are invoked to initialize | Constructors initialize the objects in


the data members of a class. your class.
| Can not return any value (not even void). | Destructors cleans up and frees

| Can accept any parameters as memory you may have allocated


needed. when the object was created.
z What would happen if we called the
member function area() before having
called function set_values()?

COP 3330 Object Oriented Programming in C++ Lecture Slides 64/134 (c) pk
2
Constructors Constructors

| Differs from other member functions. | Have the same name as the class.
| Initializes a newly created object. // classes example
#include <iostream>
| Other member functions are invoked using namespace std;
int main () {
by existing objects. class Square {
Square s(3);
cout << "area: " << s.area();
int x;
| A Constructor is invoked automatically return 0;
public:
}
when an object is created. 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;}

Constructors Constructors: Overloading

| Have the same name as the class. | You can have several constructors for
class Square { int main () { a class by overloading them.
int x; Square s;
public: cout << "area: " << s.area();
return 0; class Square {
Square(){ x = 0; };
} int x;
int area () {return (x*x);};
public:
void set_values(int a);
Square(int w){ x = w; };
int get_sidelen(void) const;
Square() { x = 0; };
};
int area () {return (x*x);};
void Square::set_values(int a){ x = a; };
void set_values(int a);
int Square::get_sidelen(void) const { return x;}
int get_sidelen(void) const;
};

Default constructor is defined for you: Square(){};

Constructors : Initialization Constructors: Warning

| Prefer initialization to assignment | If you implement no constructor, the


z Square(int w):x(w){}; compiler automatically generates a
z Array(int lowbound, int default constructor for you
highbound):size(highbound- | But if you write any constructors at all,
lowbound+1), lb ( lowbound ), hb
(highbound), data_vector(size) {}; the compiler does not supply a default
// Problematic? Why? constructor.
| List members in an initialization list in
the order they were declared.

COP 3330 Object Oriented Programming in C++ Lecture Slides 65/134 (c) pk
3
Copy Constructors Copy constructors: When is it called?

| Gets called in a number of situations. | When the return value of a function has
class type.
| If you do not write one, the compiler z Fraction process_fraction (int i, int j);
automatically generates one for you. | When an argument has class type. A copy
of the argument is made and passed to the
function
z int numerator_process (Fraction f);
| When you use one object to initialize
another object.
z Fraction a(1,3); Fraction b(a);

Copy constructors Copy constructors

| Not passed when a pointer to an | The syntax:


object is passed. z class_name(class_name const &source)

| It’s only called when a new copy of an | Const: Making a copy should not alter
existing object needs to be created. source.
| &: The function should not need to call
another copy constructor!

Copy Constructors:
Destructors
Example.
class Point {
| You can have many constructors but only
int x,y; one destructor.
| The destructor must have the same name
public:
int xx(void) const { return x;}; as the class, but preceded with a tilde sign
int yy(void) const { return y;}; (~) and it must also return no value.
Point(Point const &p){
this->x = p.xx();
| The use of destructors is especially suitable
this->y = p.yy(); 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
4
// example on constructors and destructors (from cplusplus.com)
#include <iostream>
using namespace std;

class CRectangle {
Pointers to functions
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
| Not in syllabus.
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;
}

this pointer Back to destructor example

| Useful when a member function | What will happen if we do:


manipulates two or more objects. z CRectangle r1(10,20),r2(30,40);
| It holds the address of the object for z r1 = r2;
which the member function is invoked. z The default assignment operator
| It is always passed to a non-static generated by the compiler is called.
member function. This ensures the What is wrong with that in this
right object is updated using member example?
functions.

// example on constructors and destructors (from cplusplus.com)


#include <iostream>
using namespace std;

class CRectangle {
Assignment operators
int *width, *height;
public:
CRectangle (int,int); | int x;
~CRectangle ();
int area () {return (*width * (*height));} | x = 4;
};
| 4 = x? // non-lvalue in assignment
CRectangle::CRectangle (int a, int b) {
width = new int;
| x = y = z = 8;
height = new int; z Z is assigned 8 first
*width = a; *height = b;
} z Y is then assigned the value of returned by
(z = 8) which is 8.
CRectangle::~CRectangle () { delete width; delete height; }
int main () { z x is now assigned the value returned by (y =
CRectangle rect (3,4), rectb (5,6); 8) which is 8
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 67/134 (c) pk
5
Assignment operators Assignment operators

| Complex x, y, z; | Square s1 = s2;


| x = (y = z); | The default behavior : Performs
| Writing this in equivalent functional simple member by member copy.
form: (This is the one generated by the compiler)
| x.operator=(y.operator=(z));
Is the assignment operator the same thing as
copy constructor?

Assignment Operator Assignment Operator

| Copy constructor initializes an object. | The syntax:


z class_name&
| Assignment operator copies values to operator=(const class_name &source)
an existing object.
| Const: Making an assignment should
not alter source.
| Hence, in some cases: Copy | &: The function should not need to call
constructor has to do more work than a copy constructors.
assignment operator.

Buf::Buf( char* szBuffer, size_t sizeOfBuffer )


{
sizeOfBuffer++; // account for a NULL terminator
An Example
buffer = new char[ sizeOfBuffer ];
if (buffer)
{
#include <iostream> memcpy( buffer, szBuffer, sizeOfBuffer );
#include <string.h> SizeOfBuffer = sizeOfBuffer;
}
using namespace std; }

class Buf Buf& Buf::operator=( const Buf &otherbuf )


{ {
public: if( &otherbuf != this )
Buf( char* szBuffer, size_t sizeOfBuffer ); {
Buf& operator=( const Buf & ); if (buffer)
void Display() { cout << buffer << endl; } delete [] buffer;

private: SizeOfBuffer = strlen( otherbuf.buffer ) + 1;


char* buffer; buffer = new char[SizeOfBuffer];
size_t SizeOfBuffer; memcpy( buffer, otherbuf.buffer, SizeOfBuffer );
}; }
return *this;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 68/134 (c) pk
6
Guidelines
| Place the common code used by the assignment
int main()
operator and the copy constructor in a separate
{ function and have each one call the function. This will
Buf myBuf( "my buffer", 10 ); make your code more compact and avoid duplication.
Buf yourBuf( "your buffer", 12 ); | A String class must copy a character string during the
copy constructor and during an assignment. If we
// Display 'my buffer' place this common code into a private member
myBuf.Display(); function
| void CopyString(const char* ptr); then both the copy
// assignment opperator
constructor and assignment operator may call this
myBuf = yourBuf;
routine to perform the copy rather than duplicate this
// Display 'your buffer'
code in each.
myBuf.Display();
}
From: http://www.acm.org/crossroads/xrds1-4/ovp.html

Guidelines Guidelines
| If your class has pointer data, you must provide an | Always implement the assignment operator
assignment operator. If writing an assignment
operator, you must also write a copy constructor. for your class; do not let the compiler
| The generated assignment operator performs generate the default assignment operator.
member-wise assignment on any data members of
your class. For pointer variables, we almost always do
| The compiler will generate a default
not want this because the data members of the copy assignment operator for your class if you do
will point to the same data as the copied object! not provide one. In order to be in complete
Worse, if one of the objects is destroyed, the data is
destroyed with it. A run-time error will occur the next control of how your class operates, always
time the remaining object tries to access the now non- provide an assignment operator.
existent data.

Guidelines Guidelines
| Check for assignment to self.
| The destructor must release any
| Disaster can result if a variable is assigned to itself.
Consider: resources obtained by an object
| X x; x = x; Suppose class X contains pointer data during its lifetime, not just those that
members that are dynamically allocated whenever an
object is created. Assignment always modifies an were obtained during construction.
existing object. The dynamic data will, therefore, be
released before assigning the new value. If we do not | Make the constructor as compact as
check for assignment to self, the above assignment possible to reduce overhead and to
will delete the existing pointer data, and then try to
copy the data that was previously deleted! minimize errors during construction.

COP 3330 Object Oriented Programming in C++ Lecture Slides 69/134 (c) pk
7
Abstraction and
Encapsulation
Classes II: Type Conversion, | Abstraction: Separation of interface
Friends, … from implementation
| Encapsulation: Combining lower level
elements to form higher-level entity.
For : COP 3330.
| Access Labels
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
(public/private/protected) enforce
abstraction and encapsulation.

Piyush Kumar

Benefits of Abstraction &


Concrete Types.
Encapsulation
| A concrete class is a class that | Class internals are protected from
exposes, rather than hides, its user-lever errors.
implementation | Class implementation may evolve
| Example : pair<> (defined in <utility>) over time without requiring change in
| Exists to bundle two data members. user-level code.
| 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

Using Typedefs to
More on Class definitions
streamline classes.

class Screen { class Screen {


public: public:
typedef std::string::size_type index;
private: private:
std::string contents; std::string contents;
std::string::size_type cursor; index cursor;
std::string::size_type height,width; 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
1
Class declaration for class
Class declaration
members.
| class Screen; // declaration of the class | Because a class is not defined until its
| Forward declaration: Introduces the name class body is complete, a class cannot
Screen into the program and indicates that have data members of its own type.
Screen refers to a class name.
| A class can have data members that
| Incomplete Type: After declaration, before
definition, Screen is an incomplete type. It’s
are pointers or references to its own
known screen is a type but not known what type.
class Human {
members that type contains. Screen window;
Human *bestfriend;
Human *father, *mother;

}

Using this pointer Using this pointer

| How do we implement the Screen | Return reference to Screen in the


class so that the following is allowed: member functions.
z myScreen.move(4,0).set(‘#’) z Screen& move(index r, index c);
z Equivalent to: myScreen.set(4,0);
z Screen& set(char);
myScreen.set(‘#’) z Implementation:
• Screen& Screen::move(index r,index c){
index row = r* width; cursor = row +c;
return *this;
}

Using this pointer Mutable data members

| Beware of const: | “Sometimes”, you might want to


const Screen& Screen::display(ostream &os) const modify a variable inside a const
{ member function.
os << contents;
return *this; | A mutable data member is a member
} that is never const (even when it is a
| myScreen.move(4,0).set(‘#’).display(cout) member of a const object).

COP 3330 Object Oriented Programming in C++ Lecture Slides 71/134 (c) pk
2
Mutable data members Guideline.
class Screen {
public:
| Never repeat code.
private:
| If you have member functions that
mutable size_t access_ctr; need to have repeated code, abstract
}; it out in another function and make
void Screen::do_display(std::ostream& os) const {
them call it (maybe inline it).
++access_ctr; // keep count of calls to any member func.
os << contents;
}

Type conversion: Revisited Type conversions: revisited

| int i; float f; | Can convert from one type into “this”


| f = i; // implicit conversion type with constructor
| f = (float)i; // explicit conversion z Bitset( const unsigned long x );
| f = float(i); // explicit conversion | How do we convert from “this” type to
something else?
z Create an operator to output the other
type
z Later.

Implicit Type conversion Beware:


class String {
| A constructor that can be called with a public:
single argument defines an implicit String( int length ); // Allocation constructor
// ...
conversion from the parameter type to };

the class type. // Function that receives an object of type String as an argument
void foo( const String& aString );
Class Sales_item {
Public: // Here we call this function with an int as argument
Sales_item(const std::string &book = “ “) int x = 100; foo( x ); // Implicit conversion: foo( String( x ) );
: isbn (book), units_sold(0), revenue(0.0) {}

}

String null_book = “9-999-9999-9”;


Item.sale_isbn(null_book); // implicit type conversion..

COP 3330 Object Oriented Programming in C++ Lecture Slides 72/134 (c) pk
3
Use of implicit type Suppressing implicit
conversion conversions.
class String {
public:
| Use “explicit” before conversion
String( char* cp ); // Constructor constructors.
operator const char* () const;
// Conversion operator to const char*
// ...
};
explicit String( char* cp ); // Constructor
void foo( const String& aString );
void bar( const char* someChars );

// main.cc
int main() {
foo( "hello" ); // Implicit type conversion char* -> String
String peter = "pan";
bar( peter ); // Implicit type conversion String -> const char*
}

Friends. Friends
| friend function/classes
| Properties
z Can access private and protected
z Friendship is granted, not taken
(more later) members of another class
z NOT symmetric
z friend functions are not member
• if B a friend of A, A not necessarily a friend of B
functions of class
z NOT transitive
• Defined outside of class scope
• if A a friend of B, B a friend of C, A not necessarily a
z A Friend declaration begins with the friend of C.
keyword “friend”

Friends Friends
– friend declarations
z friend function | Why use friends?
• Keyword friend before function prototype in z to provide more efficient access to data
class that is giving friendship. members than the function call
– friend int myfunc( int x ); z to accommodate operator functions with
easy access to private data members
– Appears in the class granting friendship
z friend class | Be careful: Friends can have access to
• Type friend class Classname in class everything, which defeats data hiding.
granting friendship | Friends have permission to change the
• If ClassOne granting friendship to ClassTwo, internal state from outside the class. Always
friend class ClassTwo; use member functions instead of friends to
appears in ClassOne's definition change state

COP 3330 Object Oriented Programming in C++ Lecture Slides 73/134 (c) pk
4
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 before
public:
// added constructors to initialize from a string or an istream
Sales_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 pointer
Sales_item& operator+=(const Sales_item&);
// other members as before

COP 3330 Object Oriented Programming in C++ Lecture Slides 74/134 (c) pk
5
Sorted Arrays As Lists
Introduction to |
|
Arrays are used to store a list of values
Arrays are contained in contiguous memory

Data Structures
z 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; Shifting array elements
For : COP 3330. while (list[i] > value) that come after the
Object oriented Programming (Using C++) { element being inserted
list[i + 1] = list[i];
http://www.compgeom.com/~piyush/teach/3330 i--;
} 4 8 13 29 37
list[i + 1] = value; Insert 6
length++; 4 6 8 13 29 37
}
Piyush Kumar

Sorted Arrays Intro To Linked Lists


| Due to the need to "shift" elements, sorted arrays are:
z Inefficient when inserting into the middle or front | A linked list is a data structure which allows efficient insertion
z Inefficient when deleting from the middle or front and deletion.
z Efficient for searching | Consists of "nodes". Each node contains:
| Since inserting and deleting are common operations, we need z A value - the data being stored in the list
to find a data structure which allows more efficiency z A pointer to another (the next) node
z Contiguous memory will not work – will always require a | By carefully keeping pointers accurate, you can start at the first
shift node, and follow pointers through entire list.
z "Random" placement requires "random" memory locations | Graphically, linked list nodes are represented as follows:
z Dynamic allocation provides "random" locations, and means
that the list can grow as much as necessary value ptr
z The maximum size need not be known – ever
• This is not true for arrays, even dynamically allocated
arrays

Linked List Info Deletion From Linked Lists


1000
| Each node is dynamically allocated, so memory 1004 6 • Given the initial linked list:
placement is "random" 1008 *0
100C
"start" 2 4 6 8 10
1010 2
2 4 6 1014 *1030
1018
101C Delete node with value 4
"start" 1020 *1010
1024 2 4 6 8 10
1028
102C
The above linked list may 1030 4 Resulting in
be stored in memory as 1034 *1004
shown to the right. 1038 2 6 8 10

COP 3330 Object Oriented Programming in C++ Lecture Slides 75/134 (c) pk
1
Insertion Into Linked Lists Linked List Nodes, Example
| Given the initial linked list: • Use a class to group the value and the pointer
class ListNodeClass
2 4 6 8 10 {
public: // Only for illustration: Bad design
int val; //Will have a list of ints
ListNodeClass *next; //Point to the next node
};
Insert node with value 5
int main()
{
2 4 6 8 10 ListNodeClass *head = 0; //Essentially, this declares a
//list, since it will point to the
5 //first node of a list. Initially,
//list is empty (null pointer)
Resulting in
head = new ListNodeClass; //Note no [] - not
//declaring an array - just
2 4 5 6 8 10 //one single node
...

Printing a List (Visiting Each


Try To Insert To Front Of List
Node) else
{
void printList(ListNodeClass *head) temp->next = head;
bool insertAtHead1(ListNodeClass *head,
head = temp;
{ int newVal)
}
{
ListNodeClass *temp = head; }
bool status = true;
return (status);
ListNodeClass *temp;
}
if (temp == 0) int main(void)
{ temp = new ListNodeClass;
{
if (temp == 0)
cout << "List is Empty!" << endl; {
ListNodeClass *head1 = 0;
} printList(head1);
cout << "Unable to alloc node"
insertAtHead1(head1, 5);
else << endl;
insertAtHead1(head1, 8);
status = false;
{ }
insertAtHead1(head1, 17);
while (temp != 0) printList(head1);
else
return (0);
{ {
}
cout << temp->val << " "; temp->val = newVal;
temp = temp->next; if (head == 0) List is Empty!
} {
cout << endl; temp->next = 0; List is Empty!
head = temp;
} }
}

Corrected Insert To Front Of else


Reference to pointer
List example
{
temp->next = *head;
*head = temp;
bool insertAtHead(ListNodeClass **head, }
int newVal) } // Reference to pointer example
return (status);
{
bool status = true; }
#include <iostream>
ListNodeClass *temp; using namespace std;
int main(void)
temp = new ListNodeClass;
{
if (temp == 0)
{
ListNodeClass *head = 0; void increment(int*& i) { i++; }
printList(head);
cout << "Unable to alloc node"
insertAtHead(&head, 5);
<< endl;
status = false;
insertAtHead(&head,
insertAtHead(&head,
8);
17);
int main() {
}
else
printList(head); int* i = 0;
{
temp->val = newVal;
}
return (0);
cout << "i = " << i << endl; 0
increment(i); 4
if (*head == 0)
{ List is Empty! cout << "i = " << i << endl;
temp->next = 0;
*head = temp; 17 8 5 }
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 76/134 (c) pk
2
Deleting From Front Of List Searching A List
int main(void)
{
bool deleteFromFront( ListNodeClass *head = 0; bool searchList(ListNodeClass *head, int val)
ListNodeClass **head) printList(head); {
{ insertAtHead(&head, 5); bool found = false;
bool status = true; insertAtHead(&head, 8);
ListNodeClass *temp; insertAtHead(&head, 17); ListNodeClass *temp = head;
printList(head);
if (*head == 0) deleteFromFront(&head); while (temp != 0 && !found)
{ printList(head);
deleteFromFront(&head);
{
cout << "Can't delete from list"
<< endl; deleteFromFront(&head); if (temp->val == val)
status = false; printList(head); {
} deleteFromFront(&head); found = true;
else return (0);
{ } }
temp = *head; else
*head = temp->next; List is Empty! {
//Free the memory we dynamically 17 8 5 temp = temp->next;
//allocated in insert function
delete temp; 85 }
} List is Empty! }
return (status); return (found);
}
Cannot delete from list!
}

The Stack Linked Structure The Queue Linked Structure


| A stack is another data structure | A queue is another data structure.
z Used to organize data in a certain way | Think of a queue as a line of people at a store
| Think of a stack as a stack of cafeteria trays z Get into the line at the back (insert)
z Person at front is served next (delete)
z Take a tray off the top of the stack
Get In Line Serve Customer
z Put washed trays on the top of the stack
Server
takeTray()
putTray()
| Can only insert at one end of the queue.
| Bottom tray is not accessed unless it is the only tray in z Inserting to a queue is usually called "enqueue()"
the stack.
z "Get In Line" in above diagram
| Since only the top of a stack can be accessed, there | Can only remove at the other end of the queue
needs to be only one insert function and one delete
z Removing from a queue is usually called "dequeue()"
function
z "Serve Customer" in above diagram
z Inserting to a stack is usually called "push"
z Deleting from a stack is usually called "pop"

Another Queue Pic: FIFO Priority Queue Pic: FIFO

| First In First out. | Highest priority goes out first.


| The STL has three container adaptor
types: stack, queue, and
© Mark Nelson
priority_queue.
© Mark Nelson

COP 3330 Object Oriented Programming in C++ Lecture Slides 77/134 (c) pk
3
The Priority Queue Linked
The Doubly-Linked List Structure
Structure | The linked list examples we've seen so far have only one
pointer
| A priority queue works slightly differently than a "normal" queue
| Often, it may be advantageous to have a node contain multiple
| Elements in a priority queue are sorted based on a priority "head" pointers "tail"
z Queue order is not dependent on the order in which
2 4 6 8
elements were inserted, as it was for a normal queue
z As elements are inserted, they are sorted such that the class DoublyLinkedListNodeClass
element with the highest priority is at the beginning of the {
priority queue DoublyLinkedListNodeClass *prev;
z When an element is removed from the priority queue, the int val;
first element (highest priority) is taken, regardless of when it DoublyLinkedListNodeClass *next;
was inserted
};
z Elements of the same priority are maintained in the order
which they were inserted
DoublyLinkedListNodeClass *head;
| Using a priority queue in which all elements have the same DoublyLinkedListNodeClass *tail;
priority is equivalent to using a "normal" queue

STL list<> Container Adaptors

| A list is a doubly linked list. | Container adaptors take sequence


| Example containers as their type arguments,
list<int> L; for example:
L.push_back(0);
L.push_front(1); z stack < vector < int > > a;
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.

Stack (Last In First Out) Stack


#include <stack> Provides: stack<T, Sequence>
| Use with vector (best/default),
z deque, or list (bad choice) Container Function Stack Adapter Function

| Basic interface: back() top()


push_back() push()
z bool empty(); pop_back() pop()
z size_type size(); empty() empty()
size() size()
z value_type& top();
z const value_type& top();
To support this functionality stack expects the underlying container
z void push(const value_type&); to support push_back(), pop_back(), empty() or size() and back()
z void pop();

COP 3330 Object Oriented Programming in C++ Lecture Slides 78/134 (c) pk
4
Stack Example. Simpler Stack example
// C++ STL Headers
#include <iostream> int main() {
#include <vector> stack<int> S;
#include <stack>
S.push(8);
int main( int argc, char *argv[] ) S.push(7);
{ S.push(4);
stack<const char *, vector<const char *> > s; assert(S.size() == 3);
// Push on stack in reverse order
s.push("order"); assert(S.top() == 4);
s.push("correct"); // Oh no it isn't ! S.pop();
s.push("the");
s.push("in");
s.push("is"); assert(S.top() == 7);
s.push("This"); S.pop();
// Pop off stack which reverses the push() order
while ( !s.empty() ) { assert(S.top() == 8);
cout << s.top() <<" "; s.pop(); /// Oh yes it is ! S.pop();
}
cout << endl;
assert(S.empty());
return( EXIT_SUCCESS ); }
} ©Phil Ottewell's STL Tutorial http://www.sgi.com/tech/stl/stack.html

#include <queue>
#include <vector>

Queue #include <list>


#include <iostream>

int main( ) { using namespace std;

// Declares queue with default deque base container


| Use with deque (default), or list. (Vector queue <char> q1;
works, but its extremely inefficient) // Explicitly declares a queue with deque base container
queue <char, deque<char> > q2;
| Basic interface: // These lines don't cause an error, even though they
z bool empty(); // declares a queue with a vector base container
queue <int, vector<int> > q3;
z size_type size(); q3.push( 10 );
z value_type& front(); // but the following would cause an error because vector has
z const value_type& front(); // no pop_front member function
// q3.pop( );
z value_type& back(); // Declares a queue with list base container
queue <int, list<int> > q4;
z const value_type& back();
z void push(const value_type&); // The second member function copies elements from a container
list<int> li1; li1.push_back( 1 ); li1.push_back( 2 );
z void pop(); 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();
Graphs
assert(Q.top() == 7);
Q.pop();

assert(Q.top() == 5);
Q.pop();

assert(Q.top() == 4);
An introduction
Q.pop();

assert(Q.top() == 2);
Q.pop();

assert(Q.top() == 1);
Q.pop();

assert(Q.empty());
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 79/134 (c) pk
5
Graphs Directed graph

| A graph G = (V,E) is composed of:


z V: set of vertices
z E ⊂ V × V: set of edges connecting
the vertices
| An edge e = (u,v) is a __ pair of
vertices
z Directed graphs (ordered pairs)
z Undirected graphs (unordered pairs)

Directed Graph Undirected GRAPH

Undirected Graph Some More Graph Applications


Graph Nodes Edges
transportation street intersections highways
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
6
World Wide Web 9-11 Terrorist Network
| Social network graph.
| Web graph. z Node: people.
z Node: web page. z Edge: relationship between
z Edge: hyperlink from one page to another. two people.

cnn.com

netscape.com novell.com cnnsi.com timewarner.com

hbo.com

sorpranos.com

Reference: Valdis Krebs, http://www.firstmonday.org/issues/issue7_4/krebs

Ecological Food Web Terminology


| Food web graph.
z Node = species.
| a is adjacent to b iff (a,b) ∈ Ε.
z Edge = from prey to predator. | degree(a) = number of adjacent
vertices (Self loop counted twice)
| Self Loop: (a,a)
a
| Parallel edges: E = { ...(a,b), (a,b)...}

a b
Reference: http://www.twingroves.district96.k12.il.us/Wetlands/Salamander/SalGraphics/salfoodweb.giff

Terminology Question

| A Simple Graph is a graph with no self | Max Degree node? Min Degree
loops or parallel edges. Node? Isolated Nodes? Total sum of
| Incidence: v is incident to e if v is an degrees over all vertices? Number of
end vertex of e. edges?

e
v

COP 3330 Object Oriented Programming in C++ Lecture Slides 81/134 (c) pk
7
QUESTION Connected graph

| How many edges are there in a graph | Undirected Graphs: If there is at least
with 100 vertices each of degree 4? one path between every pair of
vertices. (otherwise disconnected)

complete graph Trees

| Every pair of graph vertices is | An undirected graph is a tree if it is


connected and does not contain a cycle.
connected by an edge.
| Theorem. Let G be an undirected graph on
n nodes. Any two of the following
statements imply the third.
z G is connected.
z G does not contain a cycle.
z G has n-1 edges.

n(n-1)/2 edges

Representing Graphs
representation 1 1
4
2 2
4
| Two ways
z Adjacency List 3 3
• ( as a linked list for each node in the
Adjacent Initial Terminal
graph to represent the edges) |Vertex
Vertices Vertex Vertices
z Adjacency Matrix
1 2, 3, 4 1 3
• (as a boolean matrix)
2 1, 4 2 1
3 1, 4 3
4 1, 2, 3 4 1, 2, 3

COP 3330 Object Oriented Programming in C++ Lecture Slides 82/134 (c) pk
8
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?
Stable Marriage
z AM ?
z AL ?
Our next problem

COP 3330 Object Oriented Programming in C++ Lecture Slides 83/134 (c) pk
9
The problem Other Similar problems

| There are n men and n women | Given a set of colleges and students pair
them. (Internship – Company assignments)
| Each man has a preference list, so does the
| Given airlines and pilots, pair them.
woman.
| Given two images, pair the points belonging
| These lists have no ties. to the same point in 3D to extract depth
from the two images.
| Dorm room assignments.
| Devise a system by which each of the n
| Hospital residency assignments**.
men and n women can end up getting
| Your first programming assignment…
married.

Stereo Matching Example Preference Lists

st nd rd st nd rd
Man 1 2 3 Woman 1 2 3
X A B C A Y X Z
Y B A C B X Y Z
Z A B C C X Y Z

What goes wrong?

Unstable pairs: (X,C) and (B,Y)


Fact: If one knows the distance between the cameras They prefer each other to current pairs.
And the matching, its almost trivial to recover depth..

Stable Matching Another Stable Matching

st nd rd st nd rd st nd rd st nd rd
Man 1 2 3 Woman 1 2 3 Man 1 2 3 Woman 1 2 3
X A B C A Y X Z X A B C A Y X Z
Y B A C B X Y Z Y B A C B X Y Z
Z A B C C X Y Z Z A B C C X Y Z

No Pairs creating instability.

COP 3330 Object Oriented Programming in C++ Lecture Slides 84/134 (c) pk
10
Stability is Primary. Main Idea

|Any reasonable list of criteria must


contain the stability criterion.
| A pairing is doomed if it contains a
Idea: Allow the pairs to keep
shaky couple. breaking up and reforming until
they become stable

Can you argue that the couples will not


continue breaking up and reforming forever?

Men Propose
(Women dispose)
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 proposed
if (w is free)
assign m and w to be engaged
else if (w prefers m to her fiancé m')
assign m and w to be engaged, and m' to be free
else
w rejects m

Gale-Shapley Algorithm (men propose)

COP 3330 Object Oriented Programming in C++ Lecture Slides 85/134 (c) pk
11
Operator overloading
Operator C++ allows overloading of most of the standard operators. We are
allowed to define standard operators for new types.

Overloading The name of an operator, as a function, is “operator” followed by


the operator itself.
z The operator in “a - b” is named “operator-”.

For : COP 3330. Suppose we have a class MyNum, a new numerical type.
z The syntax for defining operators is
Object oriented Programming (Using C++) z ReturnType operator@(argument list…)
http://www.compgeom.com/~piyush/teach/3330 z For example:

MyNum operator-(const MyNum & a, const MyNum &b);

Piyush Kumar

Example Example
class MyNum { class MyNum {
public: public:
... ...
}; };

// With operator overloading:


// Without operator overloading:
MyNum operator+ (const MyNum& x, const MyNum& y);
MyNum add(const MyNum& x, const MyNum& y);
MyNum operator* (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)
MyNum f(const MyNum& a, const MyNum& b, const MyNum& c) {
{
return a*b + b*c + c*a;
return add(add(mul(a,b), mul(b,c)), mul(c,a)); // Yuk...
}
}

© C++ FAQ © C++ FAQ

More examples? Operator Overloading

| Here are a few of the many examples of operator | Operator overloading makes life
overloading: easier for the users of a class, not for
z myString + yourString might concatenate two the developer of the class!
std::string objects
z myDate++ might increment a Date object | Supports more natural usage.

z a * b might multiply two Number objects | Uniformity with built in types.


z a[i] might access an element of an Array object
z 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

COP 3330 Object Oriented Programming in C++ Lecture Slides 86/134 (c) pk
1
Operator Overloading:
Precedence of Operators
Another example
class Array {
public:
class Array {
public:
| Ival = jval = kval = lval
int& elem(unsigned i)
{ if (i > 99) error(); return data[i]; }
int& operator[] (unsigned i)
{ if (i > 99) error(); return data[i]; } z Right associative
private: private:
int data[100]; int data[100]; z (Ival = (jval = (kval = lval)))
}; };

int main() int main()


| Ival * jval / kval * lval
{ {
Array a; Array a; z Left associative
a.elem(10) = 42; a[10] = 42;
a.elem(12) += a.elem(13);
...
a[12] += a[13];
...
z (((Ival * jval) / kval) * lval)
} }

Operator Precedence in C++ Operator precedence


z :: -> global / class / namespace scopes
z . ->
| x == y + z;
z [] subscript | Precedence and associativity are
z () Parentheses
z Unary operators
fixed.
z Multiplicative operators | We cannot create new operators. Nor
z Additive operators
z Relational ordering
can we change the precedence,
z Relational equality associativity (grouping), or number of
z Logical and parameters.
z Logical or
z Assignment

Overloading operators Operator Overloading

| The meaning of an operator for the | Can I overload operator== so it lets


built in types may not be changed. me compare two char[] using a
z int operator+(int , int) // not allowed
string comparison?
| No: at least one operand of any
| Operators that can not be overloaded overloaded operator must be of some
z :: , .*, . , ?: 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
2
Class member Vs
Operator Overloading
non-member
Operators can be global or member. As a member function, the first operand
| Which ones should you override? becomes its object, that is, “*this”.
| Substraction operator as a friend/global :
z The ones your user wants you to. Do MyNum operator-(const MyNum & a, const MyNum & b);
not confuse your users. | As a member of class MyNum:

| Use common sense. If your class MyNum {


public:
overloaded operator makes life easier MyNum operator-(const MyNum & b) const;

and safer for your users, do it; };

otherwise don't MyNum MyNum::operator-(const MyNum & b) const


{ // Continue as usual

Member Vs Non-Member Non-Member

| If MyNum::operator- defined as | When operators are defined as


member function nonmember functions, they often must
z Num1 – Num2 be made friends.
class Sales_item {
z Num1.operator-(Num2) friend bool operator==(const Sales_item&, const Sales_item&);
friend std::istream& operator>>(std::istream&, Sales_item&);
| As a non-member function friend std::ostream& operator<<(std::ostream&, const Sales_item&);
// other members as before
z Num1 – Num2 …
}
z operator-(Num1,Num2) 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 Member Vs Non-Member

| ‘ = ‘, ‘ [] ‘ , ‘ () ‘, ‘ -> ‘ must be defined | Operators that change the state of the


as members ( else -> compile time object such as increment, decrement
error) and dereference -- usually should be
| Like assignment, compound- member functions.
assignment operators ordinarily ought | Symmetric operators like arithmetic,
to be members. (but not required) equality, relational, and bitwise
operators, are best left as non-
members.

COP 3330 Object Oriented Programming in C++ Lecture Slides 88/134 (c) pk
3
Guideline: Guideline vector ,deque ,list ,slist

| Not a good idea to overload | A class that has “+”, “=“


z The provide “+=“
z “,” , “&” , “ && “ , “||”
| Classes that will be used as the key type of
z These operators have built in an associative container should define “<“
meanings that become inaccessible if z “An Associative Container is a variable-sized
we define our own. Container that supports efficient retrieval of
elements (values) based on keys. It supports
| An operation to test whether the insertion and removal of elements, but
object is empty could be represented differs from a Sequence in that it does not
provide a mechanism for inserting an
by “operator!” (or in a good state…) element at a specific position. [1] “
Associative Containers:
set , multiset , hash_set , hash_multiset , map , multimap , hash_map , hash_multimap

Types in containers Find() example


list<MyNum> nums;
list<MyNum>::iterator nums_iter;
| Define “==“ and “<“ for types that will nums.push_back (“3”);
be stored in even sequential nums.push_back (“7”);
nums.push_front (“10”);
containers.
nums_iter = find(nums.begin(), nums.end(), “3”); // Search the list.
| Many algorithms (e.g. find()) assume if (nums_iter != nums.end())
{
that these operators exist 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


Output Operator
operators
| If you define ‘==‘ then also define ‘!=‘ | To be consistent with the IO library,
| If you define ‘<‘ then also define ‘<=, the syntax of output operator is:
>=, >’
ostream&
operator<<(ostream& out, const Your_Class_Type& s){
// any special logic to prepare object

// actual output of members


out << // …

// return ostream object


return out;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 89/134 (c) pk
4
IO operators:
Output Operators
Always Non-Member
| Generally, output operators print the | // if operator<< is a member of Sales_item
contents of the object with minimal z Sales_item item; item << cout;
formatting. They should not print a | The usage is the opposite of normal way we
newline. use output operators.

Input operator overloading Arithmetic operators

| Must deal with end of file/errors. Sales_item& Sales_item::operator+=(const Sales_item& rhs)


istream& {
operator>>(istream& in, Sales_item& s) units_sold += rhs.units_sold;
{ revenue += rhs.revenue;
double price;
return *this;
in >> s.isbn >> s.units_sold >> price;
// check that the inputs succeeded }
if (in)
s.revenue = s.units_sold * price; // assumes that both objects refer to the same isbn
else Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
s = Sales_item(); // input failed: reset object to default state {
return in; Sales_item ret(lhs); // copy lhs into a local object that we'll return
}
ret += rhs; // add in the contents of rhs
| When designing an input operator, decide return ret; // return ret by value
}
what to do about error handling.

Operator== Operator< and Sorting


//
inline bool // sort.cpp
operator==(const Sales_item &lhs, const Sales_item &rhs) //
{ #include <vector>
return lhs.units_sold == rhs.units_sold && #include <algorithm>
lhs.revenue == rhs.revenue && #include <functional>
lhs.same_isbn(rhs); #include <iostream>
}
struct associate
{
int num;
== means objects contain same data. char chr;
Also define !=
Classes which define == are easier to use with STL. (e.g. find()) 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
5
Operator< and sorting Operator< and Sorting
// Set up vectors
vector<associate> v(arr, arr+20), v1((size_t)20),
int main () v2((size_t)20);
{
vector<associate>::iterator i, j, k; // Copy original vector to vectors #1 and #2
bool operator<(const associate &x, const associate &y)
copy(v.begin(), v.end(), v1.begin());
{ associate arr[20] = copy(v.begin(), v.end(), v2.begin());
return x.num < y.num; {associate(-4, ' '), associate(16, ' '),
} associate(17, ' '), associate(-3, 's'), // Sort vector #1
associate(14, ' '), associate(-6, ' '), sort(v1.begin(), v1.end());
associate(-1, ' '), associate(-3, 't'),
ostream& operator<<(ostream &s, const associate &x)
associate(23, ' '), associate(-3, 'a'), // Stable sort vector #2
{ associate(-2, ' '), associate(-7, ' '),
return s << "<" << x.num << ";" << x.chr << ">"; stable_sort(v2.begin(), v2.end());
associate(-3, 'b'), associate(-8, ' '),
} associate(11, ' '), associate(-3, 'l'), // Display the results
associate(15, ' '), associate(-5, ' '), cout << "Original sort stable_sort" << endl;
associate(-3, 'e'), associate(15, ' ')}; 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; >
<16; >
<-8; >
<-7; >
<-8; >
<-7; >
Subscript operator
<17; > <-6; > <-6; >
<-3;s> <-5; > <-5; >
<14; > <-4; > <-4; >
<-6; > <-3;e> <-3;s>
| Must be a member-function
<-1; > <-3;s> <-3;t>
<-3;t> <-3;l> <-3;a>
| Ordinarily, a class that defines
<23; > <-3;t> <-3;b> subscript, defines two versions.
<-3;a> <-3;b> <-3;l>
<-2; > <-3;a> <-3;e> z A nonconst member returning a
<-7; > <-2; > <-2; >
<-3;b> <-1; > <-1; >
reference.
<-8; > <11; > <11; >
z A const member returning a const
<11; > <14; > <14; >
<-3;l> <15; > <15; > reference.
<15; > <15; > <15; >
<-5; > <16; > <16; >
<-3;e> <17; > <17; >
<15; > <23; > <23; >

Example Example
#include <vector>
using std::vector; int& Foo::operator[](const size_t index)
#include <iostream> {
using std::cout; using std::endl; return data[index]; // no range checking on index
}
class Foo {
public: const int& Foo::operator[](const size_t index) const
Foo(): data(100) { for (int i = 0; i != 100; ++i) data[i] = i; } {
int &operator[](const size_t); return data[index]; // no range checking on index
const int &operator[](const size_t) const; }
// other interface members
private: int main() {
vector<int> data; Foo f;
// other member data and private utility functions
}; cout << f[50] << endl;
return 0;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 91/134 (c) pk
6
Increment and Decrement Increment and Decrement
operators operator
// postfix: increment/decrement object but return unchanged value
// increment and decrement CheckedPtr CheckedPtr::operator++(int)
{
// no check needed here, the call to prefix increment will do the check
CheckedPtr operator++(int); // postfix operators CheckedPtr ret(*this); // save current value
CheckedPtr operator--(int); ++*this; // advance one element, checking the increment
return ret; // return saved state
}
CheckedPtr& operator++(); // prefix operators
CheckedPtr& operator--(); // prefix: return reference to incremented/decremented object
CheckedPtr& CheckedPtr::operator++()
{
if (curr == end)
throw out_of_range
("increment past the end of CheckedPtr");

++curr; // advance current state


return *this;
}

Calling prefix/postfix
++ / --
operators explicitly
| Advice: Make them member functions. Mytype.operator++(0); // postfix
| For consistency, Mytype.operator++(); // prefix
z Prefix operations should return a
reference to the
incremented/decremented object
z Postfix operations should return the
“old” value (and not the reference)

Call operator and


Function call operator
Function objects
#include <iostream> | Must be a member function
using std::cout; using std::endl;
| Can be overloaded for different
struct absInt {
int operator()(int val) { parameters.
return val < 0 ? -val : val;
} | Objects that have call operator
};
overloaded are often referred to as
int main() { “Function Objects”
int i = -42;
absInt absObj; // object that defines function call operator
unsigned int ui = absObj(i); // calls absInt::operator(int)
cout << i << " " << ui << endl;
return 0;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 92/134 (c) pk
7
Function Objects Template Function Objects

| A Function object, often called a functor class GenericNegate


{
or functionoid, is a computer programming public:
construct allowing an object to be invoked template <class T> T operator() (T t) const {return -t;}
};
or called as if it were an ordinary function,
usually with the same syntax. int main()
{
| An advantage of function objects in C++ is GenericNegate negate;
performance because unlike a function __int64 val = 10000000000i64;
cout<< negate(5.3333); // double
pointer, a function object can be inlined. cout<< negate(val); // __int64
}

Using count_if Using FOs with STL


// determine whether a length of a given word is 6 or more class GT_cls {
public:
bool GT6(const string &s){ GT_cls(size_t val =0) : bound(bal) {}
return s.size() >= 6; bool operator() (const string &s){
return s.size() >= bound; }
} private:
std::string::size_type bound;
}
vector<string>::size_type wc = cout << count_if ( words.begin() , words.end(), GT_cls(6))
count_if(words.begin(), << “ words 6 characters or longer” << endl;

words.end(), GT6); 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 Using FOs with STL

struct adder {
double sum;
adder() : sum(0) {};
void operator()(double x) { sum += x; } vector<int> V(100);
}; generate(V.begin(), V.end(), rand);

vector<double> V;
...
adder result = for_each(V.begin(), V.end(), adder());
cout << "The sum is " << result.sum << endl;

COP 3330 Object Oriented Programming in C++ Lecture Slides 93/134 (c) pk
8
A slight deviation STL FOs
// print.hpp | #include <functional>
#include <iostream>
| Types of function objects.
template <class T> z Arithmetic FOs:
inline void PRINT_ELEMENTS( • plus<Type>, minus<type>, multiplies<type>,
const T& collection, const char * optcstr = “” ) { divides<type>, modulus<type>, negate<type>
z Relational FOs:
typename T::const_iterator pos; • equal_to<Type>, not_equal_to<type>,
std::cout << optcstr; greater<type>, greater_equal<type>, less<type>,
for ( pos = collection.begin(); pos != collection.end(); ++pos) less_equal<type>
std::cout << *pos << ‘ ‘ ; z Logical FOs:
std::cout << std::endl;
• logical_and<type>, logical_or<type>,
} logical_not<type>

Usage: PRINT_ELEMENTS(myvec, “initialized to”);


How do we do the same thing using function objects?

Using library FOs with


STL FOs
Algorithms
| Another classification sort(svec.begin(), svec.end(), greater<string>());
z Unary FOs:
• negate<type> , logical_not<type> | Sorts the container in ascending
z Binary FOs: order.
• The rest. | The third argument is used to pass a
predicate function to use to compare
elements.

Function Adaptors and FOs Function Adaptors (FAs)

| FAs specialize and extend FOs. | Binder adaptors: bind1st, bind2nd


| FA categories z bind1st binds the given value to the
z Binders: Converts a binary FO to a first argument of the binary function
unary FO by binding one of the object. (bind2nd binds to the 2nd)
operands to a given value z count_if( vec.begin(), vec.end(),

z Negators: Reverses the truth value of bind2nd( less_equal<int>(), 10));


a predicate function.

COP 3330 Object Oriented Programming in C++ Lecture Slides 94/134 (c) pk
9
Function Adaptors Example (FAs n FOs)
#include <functional>
| Negators: using std::plus; using std::negate;

z not1 : Reverses the truth value of a #include <iostream>


unary predicate. using std::cout; using std::endl;

z not2 : Reverses the truth value of a #include <vector>


#include <algorithm>
binary predicate. using std::count_if; using std::bind2nd; using std::not1; using std::ptr_fun;
using std::less_equal; using std::vector;
| Example:
#include <iostream>
z count_if( vec.begin(), vec.end(), using std::cin;
not1(bind2nd( less_equal<int>(), 10))); #include <string>
using std::string;

bool size_compare(string s, string::size_type sz)


{
return s.size() >= sz;
} int arry[] = {0,1,2,3,4,5,16,17,18,19};

int main() { vector<int> vec(arry, arry + 10);

cout << plus<int>()(3,4) << endl; // prints 7 cout <<


count_if(vec.begin(), vec.end(),
plus<int> intAdd; // function object that can add two int values bind2nd(less_equal<int>(), 10));
negate<int> intNegate; // function object that can negate an int value cout << endl;

// uses intAdd::operator(int, int) to add 10 and 20 cout <<


int sum = intAdd(10, 20); // sum = 30 count_if(vec.begin(), vec.end(),
not1(bind2nd(less_equal<int>(), 10)));
cout << sum << endl; cout << endl;

// uses intNegate::operator(int) to generate -10 as second parameter return 0;


// to intAdd::operator(int, int) }
sum = intAdd(10, intNegate(10)); // sum = 0

cout << sum << endl;

Predicate functions Make FOs adaptable.


list<Widget *> widgetPtrs;
| Returns bool. class isOfInterest {
public:
| Should be a pure function: Only bool operator()( const Widget * pw) const;
}
depend on its input parameters.
isOfInterest sInteresting;
z F(x,y) should only depend on x,y.
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(),
| A predicate class is a FO whose widgetPtrs.end(),
operator() is a predicate. isInteresting);

z Example : less_equal<int> () If ( foundit != widgetPtrs.end() ) { // found what I was looking for.

COP 3330 Object Oriented Programming in C++ Lecture Slides 95/134 (c) pk
10
Make FOs adaptable. Make FOs adaptable.
list<Widget *> widgetPtrs; list<Widget *> widgetPtrs;
class isOfInterest { class isOfInterest : public unary_predicate<Widget *,bool> {
public: public:
bool operator()( const Widget * pw) const; bool operator()( const Widget * pw) const;
} }

isOfInterest sInteresting; isOfInterest sInteresting;

list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(), list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(),
widgetPtrs.end(), widgetPtrs.end(),
not1(isInteresting)); // ERROR not1(isInteresting));

If ( foundit != widgetPtrs.end() ) { // found what I was looking for. If ( foundit != widgetPtrs.end() ) { // found what I was looking for.

} }

Make FOs adaptable. Conversion Operators


list<Widget *> widgetPtrs;
class isActuallyBetter : | In addition to defining conversions “to”
public binary_predicate<Widget *, Widget *, bool> {
public: a class type (using constructors), we
bool operator()(const Widget * pw1, const Widget * pw2) const; can also define conversions “from” a
}
class type.
isActuallyBetter isBetter;
| Why might we need conversion
list<Widget *>::iterator foundit = find_if ( widgetPtrs.begin(),
widgetPtrs.end(), operators?
bind2nd(isBetter(), mywidget));
z Our own SmallInt ?
If ( foundit != widgetPtrs.end() ) { // found what I was looking for.

Do not use conversion


Conversion Operators
operators (unless necessary)
| Syntax: class Rational {
Public:
z operator type(); …
operator double() const;
| Always a member function };
class Rational {
Public:
class Mystring Usually should be const Rational r(1,2);

{ double d = 0.5 *r;
operator asDouble() const;
public: };
Mystring(); cout << r << “\t” << d << endl
//convert Mystring to a C-string Rational r(1,2);
operator const char * () { return s; } //... double d = 0.5 *r;
};
cout << r << “\t” << d << endl
int n = strcmp(mystr, “C-String"); //OK, automatic conversion of str
// to const char *

COP 3330 Object Oriented Programming in C++ Lecture Slides 96/134 (c) pk
11
Conversion operators Conversion operators
template<class T> template<class T>
class Array { class Array {
public: public:
Array (int lb, int hb); Array (int lb, int hb);
Array (int size); Array (int size);
T& operator[] (int index); T& operator[] (int index);
… …
} }

bool operator==(const Array<int>& lhs, const Array<int>& rhs); bool operator==(const Array<int>& lhs, const Array<int>& rhs);

Array<int> a(10); Array<int> a(10);


Array<int> b(10); Array<int> b(10);

for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
if ( a == b[i] ) … if ( a == b[i] ) …
Converted to : if (a == static_cast< Array<int> > (b(i)) …!!

Function objects revisited Conversion operators

| Design function objects for pass-by- | Only one class-type conversion is applied
value by the compiler. (else, compile time error)
| Used carefully, class-type conversions can
Template< class InputIterator, class Function > greatly simplify code. Used too freely, they
Function for_each(InputIterator first, InputIterator last,
Function f); can lead to mysterious errors.

| Section 13.5.1, 13.5.2 and 14.9.3+ omitted.


| Keep them small, and don’t inherit | Reading assignment: Chapter 12-14.
them.

COP 3330 Object Oriented Programming in C++ Lecture Slides 97/134 (c) pk
12
OOP
Object Oriented Object 3

Programming Object 2
Object 1

Object 4
For : COP 3330.
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330 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
Piyush Kumar , all understand addition.

OOP components Recap: ADTs

| Data Abstraction | specify the meaning of the


z Information Hiding, ADTs operations independent of any
| Encapsulation implementation/definition.
| Type Extensibility
z Least common denominator of all
z Operator Overloading
possible implementations.
| Inheritance
z Code Reuse z Information Hiding: Do not

| Polymorphism expose unnecessary information.

Inheritance Inheritance

| Two example classes | Two example classes


| Class Employee | Class Manager

class Employee { class Manager {


public: public:
Employee(string theName, float PayRate); Manager(string theName, float PayRate);
string Name() const; void set_manages(int n);
float PayRate() const; string Name() const;
float compute_pay(float hoursWorked) const; float PayRate() const;
protected: float compute_pay(float hoursWorked) const;
string name; protected:
float payrate; string name;
}; float payrate;
int manages_n_employees;
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 98/134 (c) pk
1
Reuse Manager
| We have done unnecessary work to create class Manager : public Employee { // is a relationship
Manager, which is similar to (and really is a public:
“is a") Employee. Manager(string theName, float PayRate, int n);
| We can fix this using the OO concept of void set_manages(int n);
protected:
inheritance. int manages_n_employees;
| We let a manager inherit from an employee. };
z A manager gets all the data and functionality
of an employee after inheritance. Methods of Manager have access to name, payrate because they were
z We can then add any new data and methods declared in Employee as "protected” .
needed for a manager and redefine any
methods that differ for a manager.

More on Inheritance :
Inheritance
Access privileges.
| In a public inheritance: | Derive a new class (subclass) from an
z Public members are accessible to existing class (base class).
derived class. z Syntax:
z Protected members are accessible to • class classname : access-label base-class { … }
• Access-labels = { public, private, protected }
derived class. These members are not
accessible to the users of the base
class.
| Inheritance creates a hierarchy of
related classes (types) which share
z But private are not.
code and interface.

More Examples More Examples


Person
Base Class Derived Classes
Student GradStudent
UnderGradStudent Student Employee
Shape Circle
Triangle
Rectangle
GradStudent UnderGradStudent Non-Faculty Faculty
Tetrahedron
Loan CarLoan
HomeImprovementLoan
MortgageLoan
Tenure Teaching

“Is a” relationships.

COP 3330 Object Oriented Programming in C++ Lecture Slides 99/134 (c) pk
2
Inheritance: Subclass Inheritance

| Code reuse | Derived classes contain their base


• derive GradStudent from Student classes as subobjects.
(also adds fields/methods)
Manager object.
| Specialization: Customization
• derive bounded-stack from stack string name; Employee object
(by overriding/redefining push) float payrate;
int manages_n_employees;

| Generalization: Factoring Commonality | Functions in the derived may use


z Avoid code-duplications (why?) members from the base.
There is no requirement that the compiler lay out the base and derived parts
of an object contiguously.

Inheritance Open-Closed principle in OOP

| A class must be defined to be used as a | The open/closed principle states


base class. that a class must be both open and
| A derived class can be used as a base- closed.
class.
z Open: means it has the ability to be
| Forward declarations are same for base- extended
classes as well as derived classes.
z Closed: means it cannot be modified
z class Manager;
other than by extension.
z class Employee;
z class Manager: public employee; // Error

Open-Closed Principle Open-Closed principle in OOP

| Open for extension | The idea is that once a class has


| Closed for modification been approved for use having gone
through code reviews, unit tests, and
other qualifying procedures, you don't
An interesting paper:
http://www.craiglarman.com/articles/The%20Importance%20of%20Being%20Closed%20-%20Larman%20-%20IEEE%20Software.pdf
want to change the class very much,
just extend it.

COP 3330 Object Oriented Programming in C++ Lecture Slides 100/134 (c) pk
3
Example : Open-Closed Pr. More on Inheritance
Queue TestQueue
| A pointer to a derived class can
always be used as a pointer to a base
Client (Composition) class when public inheritance is used.
(But not vice-versa)
Subclass (Inheritance) z Private base classes are different
| STL Containers which need to contain
both base/derived classes should be
DeltaBoundedQueue TestBoundedQueue made of pointers to base classes.
z Otherwise : Slicing problem.

Virtual Methods Example


class Base {
public:
int i;
| A base class must indicate which of virtual void print()
its member functions it intends its Base *bp; {
Derived d;
cout << "i value is " << i
derived classes to redefine. bp = &d;
<< " inside object of type Base\n\n";
bp->print(); // invokes
| These member functions are defined }
};
as “virtual” in the base class.
class Derived: public Base {
public:
virtual void print()
{ cout << "i value is " << i
<< " inside object of type Derived\n\n"; }
};

Dynamic Binding Dynamic Vs Static Binding

| Allows invocation of general methods | Static Binding: The compiler uses the
using a base class pointer. type of the pointer to find out which
| The fact that a reference or pointer method to call.
might refer to either a base or derived- | Dynamic Binding: The decision is
class object is the key to dynamic made at runtime. (uses ‘virtual’
binding. keyword)
| Allows easy extensibility.

COP 3330 Object Oriented Programming in C++ Lecture Slides 101/134 (c) pk
4
Dynamic Vs Static Binding Dynamic Vs Static Binding

| Static Binding | Efficiency Vs Flexibility


z Less time and space overhead. | Static Binding
z Inlining possible z More efficient
| Dynamic Binding • Less time and space overhead, can use inlining.
| Dynamic Binding
z Extensibility
z Flexible: Enables extension of behavior of a
z Better code-reuse. system easily.

Virtual Functions An example base class


// Item sold at an undiscounted price
// derived classes will define various discount strategies
| Have a fixed interface. class Item_base {
friend std::istream& operator>>(std::istream&, Item_base&);
| Derived implementations can change. friend std::ostream& operator<<(std::ostream&, const Item_base&);
public:
virtual Item_base* clone() const { return new Item_base(*this); }
| Dispatched using object’s “dynamic public:
Item_base(const std::string &book = "", double sales_price = 0.0): isbn(book), price(sales_price) { }
type” to select the appropriate
std::string book() const { return isbn; }
method.
// returns total sales price for a specified number of items
| “Once Virtual, always virtual” rule. // derived classes will override and apply different discount algorithms
virtual double net_price(std::size_t n) const { return n * price; }
z Once a base-class defines a function // no work, but virtual destructor needed
as virtual, it remains virtual through // if base pointer that points to a derived object is ever deleted
virtual ~Item_base() { } // Always virtual. Why? (Hint: Static Vs Dynamic Binding)
out the inheritance hierarchy. private:
std::string isbn; // identifier for the item
protected:
double price; // normal, undiscounted price
};

Out of scope of this class.


Do not use.

Scoping rules Scoping Rules.

| In a public base class, public and | Private derivation:


protected members of the base class z public base class members are private in
derived class.
remain public and protected members z Example: class stack: private linkedList
of the derived class. stack s;
z Example: class circle: public point s.insert(1,2); cannot call
linkedList::insert(int,int)
circle c;
| Protected derivation:
//can call point::move(int,int) z public base class members are protected in
c.move(1,2); derived class.

COP 3330 Object Oriented Programming in C++ Lecture Slides 102/134 (c) pk
5
“Is a” Vs “Has a” OOP Shape Example

ƒ Inheritance
ƒ Considered an “Is a” class relationship shape
ƒ e.g.: An HourlyEmployee “is a” Employee
ƒ A Convertible “is a” Automobile
rectangle
ƒ A class contains objects of another class
as it’s member data circle ••••
triangle
ƒ Considered a “Has a” class relationship
ƒ e.g.: One class “has a” object of another
class as it’s data

Public inheritance: “Is A” relationships

Abstract Base class: Shape. C++ Shape example


class Shape {
public: class Triangle: public Shape {
Shape ( Point2d& position, Color& c) : center_(position) , color_ (c) {}; public:
virtual void rotate( double radians ) = 0; Triangle( Point2d& p[3] );
virtual bool draw(Screen &) = 0; virtual void rotate ( double radians ){…}
virtual ~Shape(void) = 0; virtual bool draw(Screen &s) {…};
void move(Point2d& p) { _center = p; }; virtual ~Triangle(void) {…};
private:
Point2d center_; private:
Color color_; Point2d vertices[3];
}; Color color_;
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 103/134 (c) pk
6
OOP components

Inheritance | Data Abstraction


z Information Hiding, ADTs
| Encapsulation
| Type Extensibility
For : COP 3330.
z Operator Overloading
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
| Inheritance
z Code Reuse
| Polymorphism

Piyush Kumar

UML
“Is a” Vs “Has a” Another Example
Vehicle

ƒ Inheritance class Car : public Vehicle {


public:
ƒ Considered an “Is a” class relationship // ... Car
};
ƒ e.g.: An HourlyEmployee “is a” Employee
ƒ A Convertible “is a” Automobile We state the above relationship in several ways:
* Car is "a kind of a" Vehicle
ƒ A class contains objects of another class * Car is "derived from" Vehicle
as it’s member data * Car is "a specialized" Vehicle
* Car is the "subclass" of Vehicle
ƒ Considered a “Has a” class relationship * Vehicle is the "base class" of Car
* Vehicle is the "superclass" of Car (this not as common in the C++ community)
ƒ e.g.: One class “has a” object of another
class as it’s data

Virtual Functions Virtual Destructor rule

| Virtual means “overridable” | If a class has one virtual function, you


| Runtime system automatically invokes want to have a virtual destructor.
the proper member function. | A virtual destructor causes the
compiler to use dynamic binding when
| Costs 10% to 20% extra overhead calling the destructor.
compared to calling a non-virtual | Constructors: Can not be virtual. You

function call. should think of them as static member


functions that create objects.

COP 3330 Object Oriented Programming in C++ Lecture Slides 104/134 (c) pk
1
Pure virtual member
Pure virtual.
functions.
| A pure virtual member function is a | Specified by writing =0 after the
member function that the base class function parameter list.
forces derived classes to provide.
| A pure virtual function makes a class
an abstract base class (ABC)
z Can not be instantiated!
| An ABC can also have a pure virtual
destructor.

OOP Shape Example Abstract Base class: Shape.


ABC
class Shape {
public:
shape 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.
rectangle int ObjectID() const; // Do not redefine.
void move(Point2d& p) { _center = p; };
circle •••• private:
triangle Point2d center_;
Color color_;
};

Public inheritance: “Is A” relationships

C++ Shape example Concrete derived class

class Triangle: public Shape { | Has no pure virtual functions.


public:
Triangle( Point2d& p[3] ); | Simply provides the definition of all
virtual void rotate ( double radians ){…}
virtual bool draw(Screen &s) {…};
the pure virtual functions in its ABC.
virtual ~Triangle(void) {…};
// Can use the default error
// Must not define / declare ObjectID

private:
Point2d vertices[3];
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 105/134 (c) pk
2
Typecasts Containers and Inheritance

| Can I convert a pointer of a derived | Because derived objects are “sliced


class type to a base class type? down” when assigned to a base
z ? object, containers and types related
z Does it require a typecast? 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 Inheritance

| How can a class Y be a kind-of | Except for friendship, inheritance is


another class X as well as get the bits the strongest relationship that can be
of X? expressed in C++, and should be only
z Is-a relationship be used when it's really necessary.
| How can a class Y get the bits of X
without making Y a kind-of X?
z Has a relationship

Virtual and Multiple


Multiple Inheritance
Inheritance
| Multiple inheritance refers to a feature of | Multiple and virtual Inheritance:
object-oriented programming languages in
which a class can inherit behaviors and
Beyond the scope of this class.
features from more than one superclass.
| Multiple inheritance can cause some
confusing situations (A Diamond!)
z Java compromises. (can inherit
implementation from only one parent).
| Virtual inheritance is used to solve problems
caused by MI.

COP 3330 Object Oriented Programming in C++ Lecture Slides 106/134 (c) pk
3
Polymorphism Polymorphism.

| Literal meaning : “Many forms” | C++ supports several kinds of static (compile-
time) and dynamic (run-time) polymorphism.
| We can use the “many forms” of z Static Polymorphism
derived and base classes • Function/Operator Overloading
interchangeably. • Class/function templates
| The fact that static and dynamic types z Dynamic polymorphism
of references and pointers can differ is • Polymorphism through inheritance/Virtual
the cornerstone of how C++ supports member functions
polymorphism.

RTTI: Run time type


Polymorphism : Example
#include <iostream>
identification.
C++ has the ability to determine the type of a program's
class Bird // the "generic" base class
{ object/variable at runtime.
public:
class base {
virtual void OutputName() {std::cout << "a bird";}
virtual ~Bird() {}
virtual ~base(){}
}; };

class Swan : public Bird // Swan derives from Bird class derived : public base {
{ public:
public: virtual ~derived(){}
void OutputName() {std::cout << "a swan";} // overrides virtual function
int compare (derived &ref);
};
};
int main()
{ int my_comparison_method_for_generic_sort (base &ref1, base &ref2)
Bird* myBird = new Swan; // Declares a pointer to a generic Bird, {
// and sets it pointing to a newly-created Swan. derived & d = dynamic_cast<derived &>(ref1); // rtti used here
myBird->OutputName(); // This will output "a swan", not "a bird". // rtti enables the process to throw a bad_cast exception
delete myBird;
// if the cast is not successful
return 0;
} return d.compare (dynamic_cast<derived &>(ref2));
}

Inheritance Guidelines Inheritance


| Differentiate between inheritance of interface and
| Prefer minimal classes. inheritance of implementation
z D&C: Small classes are easier to z Member function interfaces are always inherited.
z Purpose of pure virtual function is to have derived
write, get right, test, use … classes inherit a function interface only.
| Prefer composition to inheritance. z Purpose of declaring a simple virtual function is to
have derived classes inherit a function interface as
| Avoid inheriting from classes that well as a default implementation.
z Purpose of non-virtual function is to have a derived
were not designed to be base classes. class inherit a function interface as well as a
mandatory implementation.
| Prefer providing abstract interfaces.

COP 3330 Object Oriented Programming in C++ Lecture Slides 107/134 (c) pk
4
Inheritance Inheritance and templates.

| Never redefine an inherited non-virtual | Consider the two design problems


function. z A stack of objects. Each stack is
homogeneous. You might have a stack of
| Never redefine an inherited default ints, strings, …
parameter value. z Classes representing monkeys. You need
z Virtual functions are dynamically several different classes representing
bound but default parameter values monkeys (each breed is a little different).
are statically bound. | Sound similar? They result in utterly
different software design.

Some real interview


Inheritance and templates.
questions.
| With both stacks and monkeys, you are | What is an explicit constructor?
dealing with variety of different types. | What is a mutable member?
(objects of type T, monkeys of breed T) | Explain the ISA and Has-A class
| Question you want to ask yourself: relationships. How would you implement
z Does the type T affect the behavior of the each in a class design?
class? | What is a virtual destructor?
• Nope : Use templates
| What is the difference between a copy
• Yup: You need virtual functions?
constructor and an overloaded assignment
operator?

Your next assignment. BigNumber


class BigNumber {
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();
BigInteger BigRational
}

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
5
Your library should … Graph libraries

BigInteger i1(7); //default bit length = 128bits | LEDA


BigRational r2(32,7); //represents 32/7 z http://www.mpi-sb.mpg.de/LEDA/MANUAL/graph.html
BigInteger & n1 = i1;
BigRational & n2 = r2;
BigRational n3 = n1 * n2; // n3 should be a Rational
| Boost Graph
// whose value is 32 z http://www.boost.org/libs/graph/doc/graph_concepts.html
n1 = (n1 + n3) + n1; // n1 should be an Integer
// n1 = 7 + 32 + 7 = 46
cout << 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.

COP 3330 Object Oriented Programming in C++ Lecture Slides 109/134 (c) pk
6
Contents

Profiling tools „ Introduction


‰ Software optimization process , optimization
traps and pitfalls
‰ Tests / Benchmark
„ Performance tools overview
‰ Optimizing compilers
‰ System Performance monitors
Piyush Kumar „ Profiling tools
‰ GNU gprof
for COP 3330. ‰ Valgrind
„ What does it mean to use system efficiently

Slide source : Vitaly Kroivets

Profiling Tools 1 Profiling Tools 2

The Problem The Software Optimization Hotspots are areas in

Process your code that take a


long time to execute

„ PC speed increased 500 times since 1981, but


today’s software is more complex and still hungry for Create
tests/benchmark Find hotspots
more resources
„ How to run faster on same hardware and OS
architecture? Retest using
‰ Highly optimized applications run tens times faster than benchmark Investigate causes
poorly written ones.
‰ Using efficient algorithms and well-designed
implementations leads to high performance applications Modify application

Profiling Tools 3 Profiling Tools 4

Extreme Optimization Pitfalls Key Point:


Corollary: Premature optimization is root
of all evil.

„ Large application’s performance cannot be improved


before it runs
„ Build the application then see what machine it runs Software optimization doesn’t
on begin where coding ends –
„ Runs great on my computer… It is ongoing process that
„ Debug versus release builds starts at design stage and
„ Performance requires assembly language continues all the way through
programming development
„ Code features first then optimize if there is time
leftover

Profiling Tools 5 Profiling Tools 6

COP 3330 Object Oriented Programming in C++ Lecture Slides 110/134 (c) pk
1
Attributes of good tests/benchmark

Tests / Benchmarks „ Repeatable (consistent measurements)


‰ Remember system tasks , caching issues
‰ use minimum performance number?
„ Representative
‰ Execution of typical code path, mimic how
Implement before you touch your code. customer uses the application
‰ Poor benchmarks : Using QA tests

Profiling Tools 7 Profiling Tools 8

Test/Benchmark attributes (cont.) How to find performance bottlenecks

‰ Determine how your system resources, such as


„ Easy to run memory and processor, are being utilized to identify
„ Verifiable system-level bottlenecks
‰ Measure the execution time for each module and
„ Measure Elapsed Time vs. other number function in your application
„ Use benchmark to test functionality ‰ Determine how the various modules running on
‰ Algorithmic tricks to gain performance may break your system affect the performance of each other
the application… ‰ Identify the most time-consuming function calls and
call sequences within your application
‰ Determine how your application is executing at the
processor level to identify microarchitecture-level
performance problems
Profiling Tools 9 Profiling Tools 10

Performance Tools Overview Using Optimizing Compilers

„ Timing mechanisms „ Always use compiler optimization settings to


‰ Stopwatch : UNIX time tool build an application for use with performance
„ Optimizing compiler (easy way) tools
„ System load monitors „ Understanding and using all the features of
‰ vmstat , iostat , perfmon.exe, Vtune Counter, top an optimizing compiler is required for
„ Software profiler maximum performance with the least effort
‰ Gprof, VTune, Visual C++ Profiler, IBM Quantify
„ Memory debugger/profiler
‰ Valgrind , IBM Purify, Parasoft Insure++

Profiling Tools 11 Profiling Tools 12

COP 3330 Object Oriented Programming in C++ Lecture Slides 111/134 (c) pk
2
Optimizing Compiler : choosing Optimizing Compiler’s effect
optimization flags combination

Profiling Tools 13 Profiling Tools 14

Optimizing Compilers: Conclusions Profilers

„ Some processor-specific options still do not


appear to be a major factor in producing fast „ Profiler may show time elapsed in each function and
its descendants
code ‰ number of calls , call-graph (some)
„ More optimizations do not guarantee faster
code „ Profilers use either instrumentation or sampling to
„ Different algorithms are most effective with identify performance issues
different optimizations
„ Idea : use statistics gathered by profiler as
input for compiler/linker

Profiling Tools 15 Profiling Tools 16

Sampling vs. Instrumentation Profiling Tools


Old, buggy and
Sampling Instrumentation inaccurate
Overhead Typically about 1% High, may be 500% !

System-wide Yes, profiles all app, drivers, OS functions Just application and

„ Gprof
profiling instrumented DLLs

Detect unexpected Yes , can detect other programs using OS No


events resources

Setup None Automatic ins. of data


collection stubs required „ Prof (less extensive than gprof)
Data collected Counters, processor an OS state Call graph , call times,

Data granularity Assembly level instr., with src line


critical path
Functions, sometimes
„ Valgrind Is not profiler
really …
statements
Detects algorithmic No, Limited to processes , threads Yes – can see algorithm,
issues call path is expensive

man gcov/gprof/prof

Profiling Tools 17 Profiling Tools 18

COP 3330 Object Oriented Programming in C++ Lecture Slides 112/134 (c) pk
3
Using gprof GNU profiler

GNU gprof „ Compile and link your program


enabled
with profiling
cc -g -c myprog.c utils.c -pg
cc -o myprog myprog.o utils.o -pg
„ Execute 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 exiting
Instrumenting profiler for every UNIX- ‰ Program should exit using exit() function
like system „ Run gprof to analyze the profile data
‰ gprof a.out

Profiling Tools 19 Profiling Tools 20

Example Program Understanding Flat Profile

„ 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

Profiling Tools 21 Profiling Tools 22

Flat profile : %time Flat profile: Cumulative seconds

This is cumulative total number of


seconds the spent in this functions, plus the
time spent in all the functions above this one

Percentage of the total execution


time your program spent in this function.
These should all add up to 100%.

Profiling Tools 23 Profiling Tools 24

COP 3330 Object Oriented Programming in C++ Lecture Slides 113/134 (c) pk
4
Flat profile: Self seconds
Flat profile: Calls
Number of seconds accounted
for this function alone Number of times
was invoked

Profiling Tools 25 Profiling Tools 26

Flat profile: Self seconds per call Flat profile: Total seconds per call
Average number of sec per call Average number of seconds spent
Spent in this function alone in this function and its descendents
per call

Profiling Tools 27 Profiling Tools 28

Call Graph : call tree of the program


Call Graph : understanding each line

Total time propagated


Called by : Unique into this function by its Number of times
index of this children was called
main ( )
function
Current
Function:
g( )

Descendants:
Current doit ( ) Percentage of the `total‘ total amount of
Function: time spent in this function time spent in
and its children. this function
g( )
Profiling Tools 29 Profiling Tools 30

COP 3330 Object Oriented Programming in C++ Lecture Slides 114/134 (c) pk
5
Call Graph : parents numbers Call Graph : “children” numbers

Time that was propagated


from the function's children Number of times this parent
called the function `/‘ Number of times this function
into this parent

Call Graph : understanding each line total number of times the called the child `/‘
function was called total number of times this
Time that was propagated child was called
directly from the function
into this parent Current Current
Function: Function:
g( ) g( )

Amount of time that was


propagated directly
from the child into function

Amount of time that was propagated


from the child's children to the function
Profiling Tools 31 Profiling Tools 32

How gprof works


„ Instruments program to count calls
„ Watches the program running, samples the PC every 0.01 sec
‰ Statistical inaccuracy : fast function may take 0 or 1 Valgrind
samples
‰ Run should be long enough comparing with sampling
period
‰ Combine 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 time Multi-purpose Linux x86 profiling tool
„ number-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 33 Profiling Tools 34

Valgrind Toolkit Memcheck Features

„ Memcheck is memory debugger „ 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
‰ detects memory-management problems intercepted
„ Cachegrind is a cache profiler „ Memcheck can detect:
‰ performs detailed simulation of the I1, D1 and L2 caches in ‰ Use of uninitialised memory
your CPU ‰ Reading/writing memory after it has been free'd
‰ Reading/writing off the end of malloc'd blocks
„ Massif is a heap profiler ‰ Reading/writing inappropriate areas on the stack
‰ performs detailed heap profiling by taking regular ‰ Memory leaks -- where pointers to malloc'd blocks are lost forever
snapshots of a program's heap ‰ Passing of uninitialised and/or unaddressible memory to system calls
‰ Mismatched use of malloc/new/new [] vs free/delete/delete []
„ Helgrind is a thread debugger ‰ Overlapping src and dst pointers in memcpy() and related functions
‰ Some misuses of the POSIX pthreads API
‰ finds data races in multithreaded
‰ programs

Profiling Tools 35 Profiling Tools 36

COP 3330 Object Oriented Programming in C++ Lecture Slides 115/134 (c) pk
6
Memcheck Example Memcheck Example (Cont.)

Access of
unallocated
memory „ Compile the program with –g flag:
‰ g++ -c a.cc –g –o a.out Debug
leaks
Using non-
initialized
value „ Execute valgrind :
‰ valgrind --tool=memcheck --leak-check=yes a.out > log

Executable
Memory Using “free” of
leak memory allocated „ View log name

by “new”
Profiling Tools 37 Profiling Tools 38

Memcheck report Memcheck report (cont.)


Leaks detected:

S
T
A
C
K

Profiling Tools 39 Profiling Tools 40

Cachegrind How to run

„ Detailed cache profiling can be very useful for improving the


performance of the program „ Run valgrind --tool=cachegrind in front of
‰ On a modern x86 machine, an L1 miss will cost around 10
cycles, and an L2 miss can cost as much as 200 cycles the normal command line invocation
„ Cachegrind performs detailed simulation of the I1, D1 and L2 ‰ Example : valgrind --tool=cachegrind ls -l
caches in your CPU
„ Can accurately pinpoint the sources of cache misses in your „ When the program finishes, Cachegrind
code will print summary cache statistics. It also
„ Identifies number of cache misses, memory references and
instructions executed for each line of source code, with per- collects line-by-line information in a file
function, per-module and whole-program summaries cachegrind.out.pid
„ Cachegrind runs programs about 20--100x slower than normal
„ Execute cg_annotate to get annotated
source file: Source files
‰ cg_annotate --7618 a.cc > a.cc.annotated
Profiling Tools 41 PID Profiling Tools 42

COP 3330 Object Oriented Programming in C++ Lecture Slides 116/134 (c) pk
7
Cachegrind Summary output Cachegrind Summary output
D-cache reads
(memory reads) Data caches
I-cache reads D1 cache read misses READ performance
(instructions executed) I1 cache read misses
Instruction caches
performance

L2-cache data
L2-cache instruction read misses
read misses

Profiling Tools 43 Profiling Tools 44

Cachegrind Summary output Cachegrind Accuracy


D-cache writes D1 cache write
(memory writes) misses „ Valgrind's cache profiling has a number of
Data caches
WRITE performance
shortcomings:
‰ It doesn't account for kernel activity -- the effect of system
calls on the cache contents is ignored
‰ It 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
L2-cache data what's happening in the cache
write misses

Profiling Tools 45 Profiling Tools 46

Massif tool Executing Massif


„ Massif is a heap profiler - it measures how much heap memory „ Run valgrind –tool=massif prog
programs use. It can give information about:
‰ Produces following:
‰ Heap blocks
„ Summary
‰ Heap administration blocks Space (in bytes)
„ Graph Picture
‰ Stack sizes multiplied by time
„ Report (in milliseconds).
„ Help to reduce the amount of memory the program uses
‰ smaller program interact better with caches, avoid „ Summary will look like this:
paging ‰ Total spacetime: 2,258,106 ms.B
„ Detect leaks that aren't detected by traditional leak-checkers, such ‰ Heap: 24.0%
as Memcheck number of words
‰ Heap admin: 2.2% allocated on
‰ That's because the memory isn't ever actually lost - ‰ Stack (s): 73.7% heap, via
a pointer remains to it - but it's not in use anymore malloc(), new and
new[].

Profiling Tools 47 Profiling Tools 48

COP 3330 Object Oriented Programming in C++ Lecture Slides 117/134 (c) pk
8
Spacetime Graphs Spacetime Graph (Cont.)

„ Each band represents single line of source


code
„ It'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 49 Profiling Tools 50

Text/HTML Report example Valgrind – how it works


„ Valgrind is compiled into a shared object, valgrind.so. The shell script
Contains a lot of extra information about heap valgrind sets the LD_PRELOAD environment variable to point to
allocations that you don't see in the graph. 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


Shows places in
the program where
most memory was
allocated

Profiling Tools 51 Profiling Tools 52

Valgrind Summary Other Tools


„ Valgrind will save hours of debugging time
„ Valgrind can help speed up your programs
„ Tools not included in this presentation:
„ Valgrind runs on x86-Linux ‰ Intel’s Vtune
„ Valgrind works with programs written in any language
‰ IBM Purify
‰ Valgrind is actively maintained
„ Valgrind can be used with other tools (gdb) ‰ Parasoft Insure
„ Valgrind is easy to use
‰ KCachegrind
‰ uses dynamic binary translation, so no need to modify,
recompile or re-link applications. Just prefix command line ‰ Oprofile
with valgrind and everything works
„ Valgrind is not a toy
‰ GCC’s and GLIBC’s debugging hooks
‰ Used by large projects : 25 millions lines of code
„ Valgrind is free

Profiling Tools 53 Profiling Tools 54

COP 3330 Object Oriented Programming in C++ Lecture Slides 118/134 (c) pk
9
Writing Fast Programs CPU Architecture (Pentium 4)

„ Select right algorithm (Take COP 4531)


„ Implement it efficiently Branch
prediction
‰ Detect hotspots using profiler and fix them
„ Understanding of target system architecture is
often required – such as cache structure Instruction Instruction Instruction
retirement
fetch decode pool
„ Use platform-specific compiler extensions –
memory pre-fetching, cache control-instruction,
branch prediction, SIMD instructions er Execution
o rd
-of- n ! Units
„ Write multithreaded applications (“Hyper Out cutio
E xe
Threading Technology”)
Memory

Profiling Tools 55 Profiling Tools 56

Instruction Execution Keeping CPU Busy


„ Processors are limited by data dependencies and
Execution Units speed of instructions
‰ Keep data dependencies low
Integer „ Good blend of instructions keep all execution units
busy at same time
Integer
„ Waiting for memory with nothing else to execute is
Instruction Floating point most common reason for slow applications
pool Dispatch unit „ Goals: ready instructions, good mix of instructions
Floating point and predictable branches
‰ Remove branches if possible
Memory Load
‰ Reduce randomness of branches, avoid function
Memory Save pointers and jump tables

Profiling Tools 57 Profiling Tools 58

Memory Overview (Pentium 4) Fixing memory problems

„ L1 cache (data only) 8 kbytes „ Use less memory to reduce compulsory


„ L2 Advanced Transfer Cache (data + cache misses
instructions) 256 kbytes, 3 times slower than „ Increase cache efficiency (place items used
L1 at same time near each other)
„ L3 : 4MB cache (optional) „ Read sooner with “prefetch”
„ Main RAM (usually 64M … 4G) , 10 times „ Avoid conflicts
slower than L1 „ Avoid capacity issues
„ Add more work for CPU (execute non-
dependent instruction while waiting)

Profiling Tools 59 Profiling Tools 60

COP 3330 Object Oriented Programming in C++ Lecture Slides 119/134 (c) pk
10
References

„ SPEC website http://www.specbench.org


„ The Software Optimization Cookbook
High-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
Ladd
„ Intel VTune Performace Analyzer webpage
http://www.intel.com/software/products/vtune/

„ Gprof man page


http://www.gnu.org/software/binutils/manual/gprof-2.9.1/html_mono/gprof.html

Profiling Tools 61

COP 3330 Object Oriented Programming in C++ Lecture Slides 120/134 (c) pk
11
Templates
An introduction to Are C macros on Steroids
C++ Templates Give you the power to parametrize
Compile time computation
For : COP 3330. Performance
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330
“The art of programming programs
that read, transform, or write other programs.”
- François-René Rideau

Piyush Kumar

Generic Programming Templates

How do we implement a linked list Function Templates


with a general type inside? Class Templates
void pointers? Template templates *
Using macros? Full Template specialization
Using Inheritance?
Partial template specialization

Metaprogramming Good old C


C code
Programs that manipulate other Double square(double x) { return x*x; }
programs or themselves • sqare(3.14) Computed at compile time
Can be executed at compile time or #define square(x) ((x)*(x))
runtime. Static double sqrarg;
Template metaprograms are #define SQR(a) (sqrarg=(a), sqrarg*sqrarg)
executed at compile time.

COP 3330 Object Oriented Programming in C++ Lecture Slides 121/134 (c) pk
1
Templates Defining the template
min.hpp
Help us to write code without being
template <typename T>
tied to particular type. inline T const& min (T const& a, T const& b){
return a < b ? a : b ;
Question: How do you swap two }
elements of any type? How do you
return the square of any type?
Template parameter T.
Syntax: template < comma separated list of parameters >
For historical reasons, you can use “class” instead of
typename.

Using the template A compile time error


The process of replacing template
parameters with concrete types is called
instantiation.

inline int const& min(int const& a, int const& b){ // The following does not provide operator<
return a < b ? a : b; std::complex<float> c1,c2;
#include <iostream> }
#include <string>
#include “min.hpp” …

int main(){ min(c1,c2); // error at compile time.


int i = 12;
std::cout << “min(7,i): “ << ::min(7,i) << std::endl;
std::string s1 = “math”;
std::string s2 = “cs”; Attempt to instantiate a template for a type that doesn’t support all the
std::cout << “min(s1,s2): “ << ::min(s1,s2) << std::endl; Operations used within it will result in a compile-time error.
}

Function Templates Function Templates


template<typename T>
C++ void swap( T& a, T& b ){
template< typename T > T tmp(a); // cc required
a = b; // ao required
inline T square ( T x ) { return x*x; } b = tmp;
}
A specialization is instantiated if needed :
• square<double>(3.14) Mytype x = 1111;
Mytype y = 100101;
Template arguments maybe deduced from swap(x,y); swap<Mytype>(…) is instantiated
the function arguments square(3.14)
MyType m; … ; square(m); expands to
Note reliance on T’s concepts (properties):
square<MyType>(m) In above, T must be copyable and assignable
Compile-time enforcement (concept-checking)
Operator * must be overloaded for MyType techniques available

COP 3330 Object Oriented Programming in C++ Lecture Slides 122/134 (c) pk
2
Argument deduction Template Parameters.

template <typename T> // T is a template parameter You may have as many template
inline T const& min (T const& a, T const& b){ // a and b are call parameter.
return a < b ? a : b ; parameters as you like.
}

template <typename T1, typename T2>


min(4,7); // ok : T is int for both arguments. inline T1 min (T1 const& a, T2 const& b){
min(4,4.2); // error: First T is int, second T is double. return a < b ? a : b ;
}
Solutions:
1. min ( static_cast<double>(4), 4.2); // ok min(4,4.2); // ok : but type of first argument defines return type.
2. min<double>(4,4.2); // ok // 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.

Function Template
Template parameters.
Specialization
template <typename T1, typename T2 , typename RT > template<>
inline RT min (T1 const& a, T2 const& b){
return static_cast<RT>(a < b ? a : b); void swap<myclass>( myclass& a,
}
myclass& b){
min<int,double,double>(4,4.2); // ok: but long and tedious
a = b = 0;
template < typename RT, typename T1, typename T2 > }
inline RT min (T1 const& a, T2 const& b){
return static_cast<RT>(a < b ? a : b);
} Custom version of a template for a specific class

min<double>(4,4.2); // ok: return type is double.

Class Templates Class templates.


template<typename NumType, unsigned D> class dpoint{ Implementing a member function.
public:
NumType x[D]; template<typename NumType, unsigned D>
}; class dpoint {
public:
A simple 3-dimensional point. inline virtual void normalize (void);
dpoint<float,3> point_in_3d; }
point_in_3d.x[0] = 5.0;
point_in_3d.x[1] = 1.0; template<typename NumType, unsigned D>
point_in_3d.x[2] = 2.0; 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; }
}

Note the explicit instantiation

COP 3330 Object Oriented Programming in C++ Lecture Slides 123/134 (c) pk
3
Friend templates Member templates.
template<typename NumType, unsigned D> template <typename T>
class dpoint { class Stack {
public: private:
template<typename NT, unsigned __DIM> std::deque<T> elems; // elements
friend bool operator!= (const dpoint<NT,__DIM>& p,
const dpoint<NT,__DIM>& q); public:
void push(const T&); // store new top element
}
void pop(); // remove top element
template<typename NT, unsigned __DIM> T top() const; // return top element
bool operator!= (const dpoint<NT,__DIM>& p, bool empty() const { // return whether the stack is empty
const dpoint<NT,__DIM>& q){ return elems.empty();
//… }
}
// assign stack of elements of type T2
template <typename T2>
Stack<T>& operator= (Stack<T2> const&);
};

Member Templates Parameterized container.


template <typename T, typename CONT = std::deque<T> >
template <typename T> class Stack {
template <typename T2> private:
Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) CONT elems; // elements
{
if ((void*)this == (void*)&op2) { // assignment to itself? public:
return *this; void push(T const&); // push element
} void pop(); // pop element
T top() const; // return top element
Stack<T2> tmp(op2); // create a copy of the assigned stack bool empty() const { // return whether the stack is empty
return elems.empty();
elems.clear(); // remove existing elements }
while (!tmp.empty()) { // copy all elements
elems.push_front(tmp.top()); // assign stack of elements of type T2
tmp.pop(); template <typename T2, typename CONT2>
} Stack<T,CONT>& operator= (Stack<T2,CONT2> const&);
return *this; };
}

Member template again. Spot the problem


template <typename T, typename CONT>
template <typename T2, typename CONT2> #include <string>
Stack<T,CONT>&
Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2) // note: reference parameters
{ template <typename T>
if ((void*)this == (void*)&op2) { // assignment to itself? inline T const& max (T const& a, T const& b)
return *this; {
} return a < b ? b : a;
}
Stack<T2,CONT2> tmp(op2); // create a copy of the assigned stack
int main()
elems.clear(); // remove existing elements {
while (!tmp.empty()) { // copy all elements std::string s;
elems.push_front(tmp.top());
tmp.pop(); ::max("apple","peach"); // OK
} ::max("apple","tomato"); // ERROR
return *this; ::max("apple",s); // ERROR
} }

COP 3330 Object Oriented Programming in C++ Lecture Slides 124/134 (c) pk
4
Class Templates: Unlike
Using Specializations
function templates
Class template arguments can’t be deduced in the First declare (and/or define) the general case:
same way, so usually written explicitly: template< class T >
dpoint <double, 2> c; // 2d point class C { /* handle most types this way */ };
Class template parameters may have default values: Then provide either or both kinds of special cases as
template< class T, class U = int > desired:
class MyCls { … }; template< class T >
class C< T * > { /* handle pointers specially */ };
Class templates may be partially specialized:
template<> // note: fully specialized
template< class U > class C< int * > { /* treat int pointers thusly */ };
class MyCls< bool, U > { … }; Compiler will select the most specialized applicable
class template

Template Template
More Templates
Parameters
A class template can be a template argument
Example: template<unsigned u>
template<
template<typename ELEM> class Bag class MyClass {
>
class C { // … enum { X = u };
Bag< float > b;
};
Or even:
};
template< class E,
template<typename ELEM> class Bag
>
class C { // … Cout << MyClass<2>::X << endl;
Bag< E > b;
};

Template Metaprograms Template Metaprograms


Factorials at compile time
template<int N> class Factorial { Metaprogramming using C++ can be
public: used to implement a turning machine.
enum { value = N * Factorial<N-1>::value };
};
(since it can be used to do conditional
and loop constructs).
template<>
class Factorial<1> {
public:
enum { value = 1 };
};

int w = Factorial<10>::value;

COP 3330 Object Oriented Programming in C++ Lecture Slides 125/134 (c) pk
5
Template Metaprograms Food for thought
template< typename NumType, unsigned D, unsigned I > struct origin
{
static inline void eval( dpoint<NumType,D>& p )
You can implement
{
p[I] = 0.0;
origin< NumType, D, I-1 >::eval( p ); IF
}
};
WHILE
// Partial Template Specialization
template <typename NumType, unsigned D> struct origin<NumType, D, 0> FOR
{
static inline void eval( dpoint<NumType,D>& p )
{
p[0] = 0.0;
Using metaprogramming. And then use
};
}
them in your code that needs to run at
compile time ☺

const int D = 3; For the more challenged: Implement computation of determinant


inline void move2origin() { origin<NumType, D, D-1>::eval(*this); }; / orientation / volume using metaprogramming. (Extra credit)

Template Metaprogramming Template Metaprogramming


Examples. examples.
/*
/*
Fibonacci's Function as
C++ Template Metaprogram
Binary-to-Decimal as
*/ Template Metaprogram
template< unsigned long N > struct Fib */
usigned long const one
{
= binary<1001>::value;
enum { value = Fib<N-1>::value + template< unsigned long N > struct Bin
Fib<N-2>::value } ; {
}; enum { value = (N % 10) +
2 * Bin< N / 10 > :: value } ;
struct Fib< 1 >
};
{
enum { value = 1 } ;
}; struct Bin< 0 >
{
struct Fib< 2 > enum { value = 0 } ;
{ };
enum { value = 1 } ;
};

More metaprogramming Traits Technique

Learn and use the Boost MTL Library. Operate on “types” instead of data
How do you implement a “mean”
class without specifying the types.
For double arrays it should output
double
For integers it should return a float
For complex numbers it should return
a complex number

COP 3330 Object Oriented Programming in C++ Lecture Slides 126/134 (c) pk
6
Traits Traits
Template< typename T >
struct average_traits{
typedef T T_average; average_type(T) = T
};
average_type(int) = float
Template<>
struct average_traits<int>{
typedef float T;
}

Traits Sources

template<typename T> C++ Templates: The complete guide


typename average_traits<T>::T_average by Vandevoorde and Josuttis.
average(T* array, int N){ Template Metaprogramming by Todd
typename avearage_traits<T>::T_average Veldhuizen
result = sum(array,N); C++ Meta<Programming> Concepts
return result/N; and results by Walter E. Brown
} C++ For Game programmers by Noel
Llopis
C++ Primer by Lippman and Lajoie

COP 3330 Object Oriented Programming in C++ Lecture Slides 127/134 (c) pk
7
The user.

Advanced C++
#define private public
#define protected public
For : COP 3330.
#define class struct
Object oriented Programming (Using C++)
http://www.compgeom.com/~piyush/teach/3330

Source: Lutz Kettner.


Piyush Kumar

Revision.

Types of users Const correctness

We can distinguish between to kinds // the pointer, the data it refers to


// ---------------------------------------
of protection a design can provide: int* p;
an user that makes occasionally int* const q;
const int* r;
mistakes const int* const s;

an user that willingly tries to get // the pointer, the data it refers to
around the protection mechanism // ---------------------------------------
int* p; // non-const non-const
int* const q; // const non-const
const int* r; // non-const const
const int* const s; // const const

Const declaration This pointer and const.

struct A { struct C {
const int i; // hidden parameter: T* const this;
A() : i(42) {} void foo();
}; // hidden parameter: const T* const this;
void bar() const;
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 128/134 (c) pk
1
Make Temporary Return Objects in Make Temporary Return Objects in
C++ Classes Const C++ Classes Const

L-values: can be used for the left side Thus, we cannot write:
of an assignment, they are non-const. int i; i++ ++; // second ++ forbidden!
R-values: cannot be used for the left Or i++++;
Error: error.cpp:5: error: non-lvalue in increment
side of an assignment. . They are
const. But:
struct A {
For example the post-increment
A operator++ (int); // the post increment operator
operator requires an l-value, but is };
itself an r-value. Now, lets try: A a; a++++; //compiles!

Make Temporary Return Objects in C++ classes are often “empty”!


C++ Classes Const Empty Classes
It works, because a++ returns a temporary object of
type A.
#include <iostream>
But it probably does not do what one would expect.
Since the second ++ works on a temporary object, a using namespace std;
itself gets only incremented once.
We can forbid the second increment explicitly by struct X {
making the return type, the type of the temporary };
object, const. This should be considered for all similar
temporary return types. int main(){
struct A { cout << sizeof(X) << endl;
// the post increment operator return 0;
const A operator++ (int); }
};

Empty Classes Polymorphism


#include <iostream>
Recap: Ability to associate different
using namespace std; specific behaviors with a single
struct X { generic notation.
};
(Many forms or shapes)
class Y:public X {
}; What you have seen:
int main(){ Dynamic Polymorphism
cout << sizeof(X) << endl;
cout << sizeof(Y) << endl;
return 0;
}

EBCO: Empty base class Optimization

COP 3330 Object Oriented Programming in C++ Lecture Slides 129/134 (c) pk
2
Dynamic Polymorphism
Static Polymorphism
Example #include "coord.hpp"

// concrete geometric object class Circle


// - \bfseries not derived from any class
class Circle {
public:
void draw() const;
Coord center_of_gravity() const;
//...
};

// concrete geometric object class Line


// - \bfseries not derived from any class
class Line {
public:
void draw() const;
Coord center_of_gravity() const;
//...
};

Static Polymorphism Static Polymorphism


#include "statichier.hpp"
#include <vector>
int main()
// draw any GeoObj {
template <typename GeoObj> Line l;
void myDraw (GeoObj const& obj) Circle c, c1, c2;
{
obj.draw(); // call draw() according to type of object
} myDraw(l); // myDraw<Line>(GeoObj&) => Line::draw()
myDraw(c); // myDraw<Circle>(GeoObj&) => Circle::draw()
// process distance of center of gravity between two GeoObjs
template <typename GeoObj1, typename GeoObj2>
Coord distance (GeoObj1 const& x1, GeoObj2 const& x2) distance(c1,c2); // distance<Circle,Circle>(GeoObj1&,GeoObj2&)
{ distance(l,c); // distance<Line,Circle>(GeoObj1&,GeoObj2&)
Coord c = x1.center_of_gravity() - x2.center_of_gravity();
return c.abs(); // return coordinates as absolute values
} // std::vector<GeoObj*> coll; // ERROR: no heterogeneous
// collection possible
// draw homogeneous collection of GeoObjs std::vector<Line> coll; // OK: homogeneous collection possible
template <typename GeoObj>
void drawElems (std::vector<GeoObj> const& elems) coll.push_back(l); // insert line
{ drawElems(coll); // draw all lines
for (unsigned i=0; i<elems.size(); ++i) { }
elems[i].draw(); // call draw() according to type of element
}
}

CRTP: Curiously recurring


Static Polymorphism
template pattern
All types must be determined at General class of techniques that
compile time. consists of passing a derived class as
Heterogeneous collections can no a template argument to one of its own
longer be handled transparently. base classes.
Generated code is potentially faster // The Curiously Recurring Template Pattern (CRTP)
than dynamic polymorphism. class derived : public base<derived> {
// ...
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 130/134 (c) pk
3
CRTP CRTP: Alternative outline.
Who is my
parent?

// The Curiously Recurring Template Pattern // The Curiously Recurring Template Pattern
// (CRTP) // (CRTP)

template <typename Derived> template <typename Derived>


class CuriousBase { class CuriousBase {
//… //…

}; };

class Curious : public CuriousBase<Curious> { template <typename T>


// ... class CuriousT : public CuriousBase<CuriousT<T> > {
// Only valid if the size of CuriousBase<Curious> // ...
// can be determined independently of Curious.
}; };

CRTP Concrete Example


CRTP: Alternative outline.
Counting Objects
#include <stddef.h>

// The Curiously Recurring Template Pattern template <typename CountedType>


// (CRTP) class ObjectCounter {
private:
static size_t count; // number of existing objects

template < template<typename> class Derived > A Generic solution protected:


// default constructor
class MCuriousBase { to object counting. ObjectCounter() {
++count;
//… }

// copy constructor
}; ObjectCounter (ObjectCounter<CountedType> const&) {
++count;
}

template <typename T> // destructor


~ObjectCounter() {
class MoreCuriousT : public MCuriousBase<MoreCuriousT> { --count;
// ... }

public:
// return number of existing objects:
}; static size_t live() {
return count;
}
};

// initialize counter with zero


template <typename CountedType>
size_t ObjectCounter<CountedType>::count = 0;

CRTP Concrete Example CRTP and the current


Counting Objects assignment
#include "objectcounter.hpp"
#include <iostream>
the graph knows the node and the
template <typename CharT>
class MyString : public ObjectCounter<MyString<CharT> > {
edge class that are supposed to work
//... together, and therefore the graph
};
class passes itself as template
int main() argument to both types.
{
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;
}

COP 3330 Object Oriented Programming in C++ Lecture Slides 131/134 (c) pk
4
Another CRTP application Another CRTP application

Implement Inequality in terms of Implement Inequality in terms of


equality. equality.
class A { template <class T>
public: class Inequality {
bool operator == (const A& a) const; public:
bool operator != (const A& a) const { bool operator != (const T& t) const {
return ! (*this == a); 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 iterators
Proxy Classes
that contains all those small member
functions that are defined in terms of a
much smaller set of member
functions.

Is this legal? Proxy classes


int data[10][20]; A dynamic two-dimensional array of
void processInput(int dim1, int dim2){ integers could be declared in C++ as
int data[dim1][dim2]; follows:

} class Array2D {
… public:
int *data = new int[dim1][dim2]; Array2D( int dim1, int dim2);
// ...
};

COP 3330 Object Oriented Programming in C++ Lecture Slides 132/134 (c) pk
5
Proxy Classes Proxy Classes

Of course, in a program we would like However, there is no operator[][] in


use the array similar to the builtin C++.
(static) two-dimensional arrays and Instead, we can implement operator[]
access an element as follows: to return conceptually a one-
int main()
dimensional array, where we can
{ apply operator[] again to retrieve the
Array2D a(5,10); element.
// ...
int i = a[2][8]; // …(a[2])[8]…
}

Proxy Classes Proxy classes


class Array1D {
public: Conceptually, it represents a one-
Array1D( int dim); dimensional array.
int operator[](int i);
// ... In this application we surely do not want to
};
class Array2D {
copy the elements to actually create a one-
public: dimensional array.
Array2D( int dim1, int dim2);
Array1D& operator[](int i); 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.
The intermediate class Array1D is called proxy class,
also known as surrogate [Item 30, Meyers97].

Double Dispatch

is a mechanism that dispatches a


function call to different concrete
Smart pointers
functions depending on the runtime
types of multiple objects involved in
the call.
Lookup (Myers Item 31, More effective C++)
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
6
Smart Pointers: auto_ptr Smart Pointers: auto_ptr

Typical pointer usage. A return in the middle of the function.


An exception thrown.
void f() {
MyClass *ptrmyclass = new MyClass; Or else the function has to catch all
// … perform some operators exceptions.
delete ptrmyclass;
} How do we avoid resource leaks?
Recap: valgrind? ☺

Source of trouble!

What if you forgot a return in the middle?

Smart Pointers: auto_ptr Smart Pointers: auto_ptr


// Fixing the last program : Complicated. // header for auto_ptr
#include <memory>
void f(){
myclass ptr = new myclass; void f(){
// create and initialize an auto_ptr
try { std::auto_ptr<myclass> ptr(new myclass);
… // … perform some operators
}
}
catch( … ){
► delete and catch are no longer necessary!
delete ptr;
► The smart pointer can free the data to which it points whenever the
throw; // rethrow the exception
pointer itself gets destroyed.
}
► An auto_ptr is a pointer that serves as an owner of the object to which
it refers to.
delete ptr;
► 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 Misusing auto_ptrS.

Has much of the same interface as an Cannot share ownerships.


ordinary pointer ( operator *, operator Are not provided for arrays.
-> ) They call delete and not delete[]
Pointer arithmetic (such as ++) is not Do not do reference counting.
defined. Do NOT meet the requirements for
container elements.
Note:
When a auto_ptr is copied/assigned the
std::auto_ptr<myclass> ptr1(new myclass); // OK source auto_ptr gets modified! Because its
std::auto_ptr<myclass> ptr1 = new myclass; // Error
transfers its value rather than copying it.

COP 3330 Object Oriented Programming in C++ Lecture Slides 134/134 (c) pk
7

S-ar putea să vă placă și