By Stephen R. Davis

The C++ language contains so many features that beginning programmers cannot possibly understand every one. Fortunately, you don’t need to master all the features of the language in order to write big, real-world programs. Following are ten features that you may want to look ahead at, just in case you see them in other people’s programs.

The C++ goto command

This command goes all the way back to C, the progenitor of C++. In principle, using this command is easy. You can place goto label; anywhere you want. When C++ comes across this command, control passes immediately to the label, as demonstrated in this code snippet:

  for(;;)
  {
      if (conditional expression)
      {
          goto outahere;
      }
      // ...whatever you want...
  }
outahere:
  // ...program continues here...

In practice, however, goto introduces a lot of ways to screw up. In any case, it didn’t take long before programmers noticed that the two most common uses of the goto were to exit loops and to go to the next case within a loop. The C Standards Committee introduced break and continue and almost completely removed the need for the goto command.

The C++ ternary operator

The ternary operator is an operator unique to C and C++. It works as follows:

int n = (conditional) ? expression1 : expression2;

The ? operator first evaluates the conditional. If the condition is true, then the value of the expression is equal to the value of expression1; otherwise, it’s equal to the value of expression2.

For example, you could implement a maximum() function as follows:

int max(int n1, int n2)
{
    return (n1 > n2) ? n1 : n2;
}

The ternary operator can be applied to any type of numeric but cannot be overloaded. The ternary operator is truly an expression — not a control statement like an if.

Enumerated types in C++

The simple idea is that you can define constants and let C++ assign them values, as shown here:

enum Colors {BLACK, BLUE, GREEN, YELLOW, RED};
Colors myColor = BLACK;

The problem with enumerated types lies in the implementation: Rather than create a true type, C++ uses integers. In this case, BLACK is assigned the value 0, BLUE is assigned 1, GREEN2, and so on.

The 2011 Standard Library for C++ “fixed” this problem by creating an enumerated class type as shown in the following snippet:

enum class Colors {BLACK, BLUE, GREEN, YELLOW, RED};
Colors myColor = Colors::BLACK;

In this version, Colors is a new type. Each of the constants, BLACK, BLUE, and so on, are members of type Colors. You can still cast an object of class Colors into an int, but an implicit cast is not allowed.

C++ namespaces

It’s possible to give different entities in two different libraries the same name. For example, the grade() function within the Student library probably assigns a grade, whereas the grade() function within the CivilEngineering library might set the slope on the side of a hill. To avoid this problem, C++ allows the programmer to place her code in a separate namespace. Thus the grade within the Student namespace is different from the grade within CivilEngineering.

The namespace is above and beyond the class name. The grade() member function of the class BullDozer in the CivilEngineering namespace has the extended name CivilEngineering::BullDozer::grade().

All library objects and functions are in the namespace std. The statement at the beginning of the program template using namespace std; says that if you don’t see the specified object in the default namespace, then go look in std.

Pure virtual functions in C++

You don’t have to define a function declared virtual. Such an undefined function is known as a pure virtual member function. At that point, however, things get complicated. For example, a class with one or more pure virtual functions is said to be abstract and cannot be used to create an object. Tackle this subject after you feel comfortable with virtual functions and late binding.

The C++ string class

Most languages include a string class as an intrinsic type for handling strings of characters easily. In theory, the string class should do the same for C++. In practice, however, it’s not that simple. Because string is not an intrinsic type, the error messages that the compiler generates when something goes wrong are more like those associated with user-defined classes. For a beginner, these messages can be very difficult to interpret.

string isn’t even a class. It’s an instance of a template class. The error messages can be breathtaking.

Multiple inheritance in C++

One class can actually extend more than one base class. This sounds simple but can get quite complicated when the two base classes contain member functions with the same name. Even worse is when both base classes are themselves subclasses of some common class.

In fact, so many problems arise that C++ is the only C-like language that supports multiple inheritance. Java and C#, both languages derived from C++, decided to drop support for multiple inheritance.

C++ templates and the Standard Template Library

The makers of C++ noticed how similar functions like the following are:

int max(int n1, int n2)
{
    if (n1 > n2)
    {
        return n1;
    }
    return n2;
}
double max(double n1, double n2)
{
    if (n1 > n2)
    {
        return n1;
    }
    return n2;
}
char max(char n1, char n2)
{
    if (n1 > n2)
    {
        return n1;
    }
    return n2;
}

“Wouldn’t it be cool,” one says to another, “if you could replace the type with a pseudo-type T that you could define at compile time?” Before you know it, presto — templates become part of C++:

template <class T> T max(T t1, T t2)
{
    if (t1 > t2)
    {
        return t1;
    }
    return t2;
}

Now the programmer can create a max(int, int) by replacing T with int and compiling the result, create a max(double, double) by replacing T with double, and so forth. The Standards Committee even released an entire library of classes, known as the Standard Template Library (STL for short), based upon template classes.

For a beginner, however, the subject of template classes starts to get syntactically very complicated. In addition, the errors that the compiler generates when you get a template instantiation wrong are bewildering to an expert, never mind a beginner. This is definitely a topic that needs to wait until you feel comfortable with the basic language.