Fall 2004
Monday 3:00 - 4:00 Rm 343, Friday 2:00 - 4:00 Rm 343
C++ is a superset of C. So everything we have learned about C, in terms of commands that exist and the way things work, also applies to C++. C++ also offers a lot of additional functionality and alternative ways to do things. The main difference between C and C++ is that C++ allows object oriented programming via classes, but this topic covers other additions to C++. (Some of these additions involve classes in the sense that they involve provided classes - e.g. the C++ "string" is a provided class, not a primitive data type - but the things we talk about as part of this topic do not require the programmer to create any classes.)
C++ uses separate compilers than C. On most Unix systems with C++, the compiler g++ will be available. (Really this compiler calls gcc with a variety of parameters that allow the recognition of C++ concepts, but that is not important.) C++ has changed over the years, so depending on what version is on a system: (1) The header files you need to include may vary a bit in name; (2) Certain features may or may not be present; and (3) Certain lines (e.g. "using namespace std;") may or may not be required. I will cover the up-to-date version of C++ in class, and this is also the version I will assume in these topic summaries.
The header file <iostream> should be included at the top of almost every C++ program. This basically takes the place of <stdio.h>, although that header file can be included as well if you want to use some old-fashioned C functions such as printf. The old C libraries still exist (since C++ is a superset of C), and there is a second name for each of the old libraries (take off the ".h" from the end of the old name and insert a "c" at the start of the new name, e.g. <stdio.h> becomes <cstudio>).
One of the more visible differences from C to C++ is the way that standard output is handled. Although all of the old functions (e.g. printf) still exist, it is more common to display to standard output using the new "cout" stream and the "put to" operator "<<". Similarly, standard input is generally accessed using the "cin" stream and the "get from" operator. Another noticeable difference is that variables can now be declared just about anywhere, not just at the start of a basic block. They can even be declared, e.g., inside the header of a "for" loop.
Another common difference is the way strings are handled. C-style strings still exist, of course, and they are still sometimes used, but C++ also provides a "string" class of which string objects can be declared. During lectures, we will discuss several member functions (a.k.a. methods) provided as part of the class, and we will also see that certain operators have been overloaded for the class (e.g. "+" means concatenation). When we first discuss these concepts, before going over classes in detail, this may seem somewhat confusing, but if you look back at this summary after we cover classes, it should be more clear. A C++ style string can be converted to a C-style string using the ".c_str()" method of the string class.
In lectures, we also cover how text files are handled using "ifstream" and "ofstream" objects. Once a file stream is created, it can be handled much like "cout" (for an output file stream) or "cin" (for an input file stream). We also examine vectors, which are basically resizable arrays, and maps, which can be indexed by any type for which the less than "<" operator is defined (including user-defined classes for which this operator is overloaded). Both vectors and maps are examples of C++ "containers". Other provided containers include linked lists, stacks, and queues. Any container is guaranteed to implement certain member functions (e.g. ".size()", ".begin()", and ".end()", the latter two returning iterators).
All provided container classes have functions that return iterators to the first element in the container or to a position just after the last element. An iterator is in some ways like a pointer to an element, and shares much of the syntax associated with pointers, but they are not necessarily implemented as pointers. Iterators through the elements of a container can be explicitly declared and used, or they can be used implicitly using certain provided "algorithms", for example "for_each" and "sort". C++ also provides stream iterators which have similar uses but are declared differently.
Another powerful addition to C++ is support for generic programming. The use of templates allows us to write functions that can operate on classes of various types. Essentially, we are replacing the names of classes with pseudo-variables. We will not talk much about templates, and I will not be asking you to program with them, but it would be nice if you are aware of their existence.
Another addition to C++ is the addition of references. You can think of a reference as a pointer to an object or variable that is dereferenced automatically every time it is accessed. Better is probably to think of it as a second name for a variable. References provide a method for programmers to write functions that permanently change the values of variables that are passed as arguments. Only "l-values" can be passed to a reference parameter. An l-value is something to which you can assign a value, e.g. a variable. You can not pass a constant or the return value of a function (these things reside in temporary variables and their values can not be reassigned).
Dynamic memory allocation, which is generally less important in C++ than in C (provided classes such as vectors and maps make linked lists less important), is also handled differently. Although "malloc" and "free" still exist (since C++ is a superset of C), it is better to use the "new" and "delete" operators, There are slightly different versions of these operators for dynamic arrays of objects or primitives compared to a single object or primitive. (By primitive, I mean a standard type, such as in int, double, or a boolean, the last of which is new to C++.) If you do use malloc and need to cast the returned memory pointer, the method of casting has also changed.
Error handling in C++ is often handled with exceptions. Exceptions can be thrown and caught. You catch an exception by including the code that may cause an exception in a "try" block, which is immediately followed by one or more "catch" blocks that catch exceptions of different types. You throw an exception using the "throw" command. Really what is being thrown and caught is an object whose type (i.e. class) represents the type of exception that has occurred.
In C++ you can have multiple functions with the same name. The function that is actually called depends on which definition has parameters that match the number and types of the passed arguments. If there is no matching function or multiple and ambiguous matching functions, you will generate a compiler error. In C++ you can also overload operators, but we will not look at this further until we cover classes.
Finally, C++ provides namespaces, which seems to me to be a step towards classes. A namespace provides a method of relating a set of variables. You can reference a variable specific to a namespace by using the scope resolution operator "::". Different namespaces can have variables with the same name. Some namespaces, e.g. "std" are provided, and the line "using namespace std;" which we have been including at the top of our programs allow the variables that are part of this namespace to be used without directly referring to the namespace every time.