A Rationale/Elaboration of the APCS C++ subset

Not all aspects of the C++ language are mentioned in the AP C++ subset. In particular, the control constructs below are used in the AP C++ subset.

More esoteric language features such as operator ->* or operator .* are not part of the subset. Certainly esoteric means different things depending on one's level of C++ expertise. However, the AP C++ subset is complete enough to implement programs typically encountered in the first two courses in computer science.

Overloaded functions and operators

Function overloading is a simple form of static (or ad hoc) polymorphism and is included in the C++ subset. Operator overloading is a simple extension of function overloading, and is very useful. For instance, it allows comparison operators for strings so that comparison of string values has the same syntax as comparison of int and double values. Operator overloading is also used to support assignment and stream I/O, the operators =, <<, and >>. In C++, the return type of a function is not part of a function's signature for the purpose of resolving an overloaded function call; this is considered of minor importance and will not be tested.

Use of const

C++ uses the const keyword in many places. For example, program constants defined using const rather than with #define are accessible symbolically in many debuggers; therefore, they are preferred. A const member function indicates that the function will not modify any private data, i.e., that the function is an accessor rather than a mutator. Determining when to designate a member function as const is a design decision as well as a C++ detail and is required by AB students. The const keyword is also used in parameter-passing and function return values, usually with reference types. Here const indicates that the reference parameter or return value cannot be modified. This use of const is essential for writing safe C++ programs, so is included in the AP C++ subset. Use of const with pointers is not part of the AP C++ subset.

Templates

Templates are a fundamental construct used to achieve generalized abstraction for data structures. Templates are used to define the AP vector, matrix, stack, and queue classes. The syntax for using templates in defining and declaring variables is straightforward. The syntax for declaring and defining templated functions, especially templated member functions, is somewhat cumbersome, although not difficult. Writing templated functions is part of an AB course. Using templates often requires compiler-specific mechanisms in order to instantiate the templated functions and classes. Information on how to do this is for several compilers is provided in README files associated with the AP C++ classes.

Preprocessor

The C++ preprocessor is in many ways a relic of C and is largely obsolete. One use of hte preprocessor is for #include. The other use of the preprocessor for APCS is related to #ifndef, #define, and #endif used in header files to prevent multiple inclusion of the same file. Other uses of the preprocessor are strongly discouraged. Program constants should be defined using const rather than with #define since const values are accessible from symbolic debuggers. Parameterized macros should be discouraged since a macro-call may look like a function-call but is not semantically equivalent and is not type safe.

Increment/Decrement operators

The use of ++ and -- is a useful shorthand for incrementing and decrementing by one, respectively, i.e., x++ is a shorthand for x += 1 and x-- is a shorthand for x-=1.

The use of ++ and -- is restricted to single statements such as x++ and x--. For example, these operators should not be used in the context of larger expressions such as a[k++] = 0. Differentiating between pre- and post- increments/decrements (++x and x++) is not part of the AP C++ subset.

Break and Return

The switch statement requires break to prevent fall-through between cases. In loops, a judicious use of break can simplify coding. The undisciplined use of break statements, however, can interfere with loop design, the identification of exit conditions, and the development of loop invariants. The use of break within loops is part of the APCS C++ subset, but so are loops designed with complex Boolean loop tests. In C++, short-circuited Boolean evaluation also helps in writing and coding loops.

Similarly, the return statement causes control to leave a function. In some situations using multiple return statements in a single function makes a function easier to write and understand. For example, a return from the body of a loop can decrease the need for Boolean flag variables.

Inheritance and Streams

In C++ I/O is accomplished with streams. Input uses generic istream objects and output uses generic ostream objects. For example, both cin and ifstream objects can be used for input. Overloading of I/O functions and operators for classes is part of the APCS C++ subset. Consequently, students should realize that ifstream objects or cin can be passed as arguments to these functions. This is possible because the streams form an inheritance hierarchy. However, students are not expected to understand inheritance since inheritance is not part of the current AP C++ subset.

Libraries

There are many libraries that students will find useful in certain applications. For example, iomanip.h contains many stream formatting features that students and teachers may want to include in their programs. Similarly, math.h functions may be necessary for the correct evaluation of numerical applications. However, except for functions pow and sqrt, knowledge of the functions in these libraries will not be tested on the AP examination.

Error Handling

Recent C++ compilers support exception handling as a mechanism for handling errors. When all compilers support exception handling, this will be the preferred method for error handling despite the somewhat cumbersome syntax. Because not all compilers support exception handling, the AP C++ classes are written in two ways: one version uses exceptions and another version uses the standard function abort(). An AP-supplied function apassert() is used instead of the standard assert() function. The apassert() function also comes in two versions: one using exceptions and one using abort().