Moving From C to C++

by Randy Finch

Several years ago I wrote a function evaluator for a 3D function plotting program. It allowed the user to type in a three-dimensional equation of the form Z=F(X,Y) and then calculate the value of Z for any combination of X and Y. The function evaluator was written in C. I wrote an article about it for this magazine (October 1989). Several months ago I rewrote the function evaluator in C++ using the SAS/C Development System v6.50. I found that the code was much more organized and easier to read and modify. Occasionally, I will refer to the October 1989 article when comparing it with the new code listed at the end of this article. Also, if you need to know more details about how the function evaluator works, you will need to read the older article. So, if you have a copy, please have it at your side while reading this article.

C vs. C++

C++ adds many features to C. Some of these are stronger type checking, object-orientation, and inheritance. The first two were important to my program. Stronger type checking simply means that C++ is more persnickety about making sure that appropriate variable types are passed to functions and that variables are used in a program as they are declared. As you know, C was fairly good at type checking, but not as good as it could have been. I have been bit several times due to this laxness. Most of the changes to the function evaluator code, as opposed to its structure, were to satisfy the type checking of the C++ translator. If you compare the new code with the old, you'll see many places where type casting is used in the C++ code, but not in the C code.

The object-orientation of the code is the major enhancement to my program. A C program is made up of data and functions. Many different data types are available and data structures can be declared as custom data types. Typically a function is passed one or more variables, the function then operates on the variables, and control is returned to the calling code. In complex code, this can lead to confusion when similar, but different, functions are used to operate on similar, but different, data.

C++ gets around this problem by combining data and functions into one entity called an object. The definition of an object is called a class. A C++ class is very similar to a C data structure. It contains data, but it also contains functions. A function that appears as part of an object is called a method. Thus, an object contains both the data it needs and the code to act on this data all in one place. If a program needs to tell an object to do something, it simply calls one of the object's methods. A typical example is a vector-based graphics program that allows geometric shapes to be drawn on the screen. Each geometric shape could be an object created from a class definition. When an actual object is created in computer memory from a class definition, this is called instantiation, or creating an instance of a class. The object might contain a ChangeColor method. If the object's name is GeoShape1, then something like the following statement could be used to change its color to red: GeoShape1.ChangeColor(RED).

Typically, when defining an object in C++, two files are created: the header (.hpp) file and the code (.cpp) file. The header file, also called the definition file, contains all the #include's, #define's, structure definitions, etc. as well as the class definition. The code file, also called the implementation file contains all the methods' code. By separating the code in this way, any program that needs to use an object can simply #include the header file and the object will be available to it. It is recommended that each object have its own header and code file. This allows one object to be changed without having to recompile any other objects.

FuncEval in C++

The C++ version of my function evaluator program defines a FuncEval class that contains all the data and methods necessary for creating a function, performing syntax checking, getting error information, and evaluating for values of X and Y. The functionality is the same as the older program, but easier to understand and modify. Let's look at it.

Listing 1 contains the header file (FuncEval.hpp) for the FuncEval object. Notice that all the syntax error definitions have been incorporated into this file. They were separate in the C version. The structure definitions CharStackType and NumStackType are the same as the CharStack and NumStack definitions in the C code. It is highly recommended that when defining a structure, StructName, that the structure be named StructNameType. Immediately following the definition, a typedef statement should be used to define StructName as a new variable of type StructNameType. This is what I have done for CharStack and NumStack.

The actual class definition for FuncEval appears at the end of Listing 1. Notice that the data and methods are divided into public and private. Public data and methods can be used by an outside program, whereas private data and methods cannot. Private data and methods can only be used by the methods within the object. Generally, it is not recommended that any data be public, only methods. If data needs to be changed by a program, it should do so through a public method. In the example of the geometric shape object, the color was changed by calling a method; however, it could have been done by making the color variable public and letting the program execute the following statement: GeoShape1.Color=RED. By using a method to change the color, new features can be added to the object with no need to change the program that uses it. For the FuncEval class, all data and most methods are private. The public methods are used for converting a function string, getting an error number, message, and position, and evaluating the function for values of X and Y. When a public method has the same name as the class itself, it is called a constructor. This is a special method that executes each time the class is instantiated. The constructor is used for initializing variables and other tasks that need to be done before the object is used. Although the FuncEval class does not have one, a class can also have a destructor for cleaning up before an object is deleted. Its name is the same as the constructor but with a tilde (~) in front (e.g., ~FuncEval).

The code file for FuncEval is shown in Listing 2. All of the methods, except the constructor and the ones used for error handling, are the same as their equivalent functions in the C version with just a few exceptions. First, type casting is used in the methods to satisfy C++'s stronger type checking. Second, the method names are different than their equivalent function names. If the function name is CheckSyntax, then its equivalent method is named FuncEval::CheckSyntax. The "FuncEval::" prefix associates a method with the FuncEval class. Other objects can have a method with the same name. As for the constructor, it simply initializes the error position to zero.

Listing 3 shows a program, Main.cpp, that uses the FuncEval object to evaluate a user-defined 3D function. This program is similar to the Testfevl.c program in the October 1989 article. However, the code is somewhat different in order to interact with the FuncEval object properly. At the beginning of main() is the statement: FuncEval *func = new FuncEval. The new operator instantiates the FuncEval class, creating an actual instance of the FuncEval object in memory. The pointer to this object is named func. The rest of the program is easy to follow, but notice how FuncEval's public methods are called: func->PublicMethodName. The name of the pointer is used because the method is part of the object.

~FuncEval

I hope you have enjoyed this short introduction to converting C programs to C++. If you have any questions or comments, you can send them to me via this magazine or Email me at RandyWrite@aol.com or webmaster@rcfinch.com. Also, by the time you read this, my home page (http://fly.HiWAAY.net/~rcfinch/rcfhome.html) should be up and running. I plan to make available the text and programs from all of my articles in Amazing Computing. Check it out. I look forward to hearing from you. If you want to read more about the differences between C and C++, I highly recommend the book listed below. If you are already a C programmer and want to move to C++, you can't live without it.

Sessions, Roger; Class Construction in C and C++: Object-Oriented Programming Fundamentals; PTR Prentice Hall, Inc.; 1992.


Back to list of articles
Back to Randy Finch's Home Page
Last modified on April 1, 1996
Randy Finch at webmaster@rcfinch.com