More C++
Type bool
bool done;
done = true;
done = false;
if (done) { ... }
while ( ! done ) { ... }
Enumerated Types
enum status { single, married };
status s1 = single, s2 = married;
enum { Min = 0, Max = 100};
int minval = Min, maxval = Max;
Type string
#include <string>
string s1 = “The quick fox”;
string s2 = “ jumped over”;
string s3 = s1;
string s4(10, ‘$’); // 10 dollar signs
string filename = “salesfile”;
ifstream in;
in.open(filename.c_str());
String operations
Assignment: s1 = s2;
Concatenation: s3 = s1 + s2;
s4 += s2; // append to s4
Erase: s3.erase(4, 5); // erase 5 chars starting at
// position 4.
Replace: s1.replace(3,6, s2); // replace substring of
// of length 6 starting at
// 3 with string s2.
Comparison: ==, != , < , <= etc
if (s1 > s2) { // s1 comes after s2 alphabetically
Substring: s2 = s1.substr(3, 5);
Searching:
s1.find(s2, j); // returns smallest index >= j where s2 occurs
within s1, or string::npos if not found. Return value is of type
string::size_type.
s1.rfind(s2,j); // largest index >= j where s2 occurs within s1.
s1.find_first_of(s2); // find position of first character in s1 that
occurs in s2.
References
• A reference is an alias (alternative name) for a variable.
int x;
int& ref = x; // ref is another name for x;
ref =23;
cout << x << endl;
What gets printed?
23
void swap(int x, int y)
{ int t; t = x; x = y; y = t; }
int u = 20, v = 30;
swap(u, v);
cout << u << “ “ << v << endl;
Output: 20 30
void swap(int& x, int& y)
{int t; t = x; x = y; y = t; }
swap(u, v);
Output: 30 20
Returning references
Bad:
int& val()
{ int j;
j = 20;
return j;
}
k = val();
What’s wrong?
OK:
int & val(int a[ ], int index)
{
return a[index – 1];
}
val(a, 5) = 10; // val(a, 5) is a reference to a[4];
cout << a[4];
What gets printed?
Default arguments
void printItem(string item, float price = 5, int quantity = 1)
{
cout << item << “ “ << price << “ “ << quantity;
}
Can be invoked as:
printItem(“bananas”, 3, 10);
printItem(“pears”, 2);
printItem(“cucumbers”);
Function overloading
• We can use the same name to denote different functions as long as
they differ in the number of arguments and/or the type of the
arguments.
• A function’s signature is its name plus the number of arguments,
types of the arguments, and order of the arguments.
• For example, f(int, int), f(int, double), f(double), f (int)
int f(int x, int y) { return x + y; }
double f(int x, double y) { return x * y; }
double f(double x) { return x * x; }
f(3, 4) -> 7
f(3, 2.0) -> 6.0
f(3.0) -> 9.0
Dynamic allocation
• Instead of malloc and free we use new and delete in
C++
int * p = new int; // a single int
*p = 10;
double * a = new double[10]; // array of 10
for (int i = 0; i < 10; ++i) { a[i] = i*i; }
delete p;
delete [ ] a;
Exceptions
• Traditionally, functions used special return
values to signify that an abnormal condition
had occurred.
• Exception handling in C++ is done via
exception throwing. When a function wants
to signify that an abnormal condition has
occurred, it throws an exception.
• In order to be notified of the exception, the
caller calls the function within a try block.
• The exception is caught by a catch block.
try {
f( ); // call function f that may throw
// exception
}
catch (T1 excpt) {
// Code to handle excpt having type T1
}
catch(T2 excpt) {
// Code to handle excpt having type T2
}
...
• T1 and T2 are types (e.g. int, char, user defined)
• The actual catch block entered is determined by the type thrown.
• If a function that throws an execption is not called within a try block,
of if there is no catch clause whose argument type matches the type
of the exception being thrown, the default unexpected handler is
called (which terminates the program).
Example of exception throwing and catching
void f( int x)
{ if (x == -1) throw 1000000;
else if (x == 0) throw “zero input”;
else return x*(x-1);
}
int main( )
{ int ret;
try {
ret = f(0);
}
catch(int x) {
cout << “Exception of type int caught: “ << x << endl;
}
catch(const char *s) {
cout << “Exception of type C string caught: “ << s << endl;
}
}
Some common exceptions
• #include <stdexcept>
• out_of_range: Thrown by string operations like erase, insert, replace and
substr when the first argument (starting position) is out of bounds.
• bad_alloc: Thrown by new if there is no memory left to satisfy the request
for dynamically allocated storage. (The old malloc returns a null pointer
instead).
For example:
try {
s.erase(10, 4);
}
catch(out_of_bounds) { // triggered if position 10 in s does not exist
cerr << “Bad index\n”;
exit(1);
}