The vector class
Here are some additions to the vector class in C++.
This month, I continue our discussion of a C++ class suitable for doing math with vectors. As useful as this math is, things get even better when we combine matrix and vector operations in a single set of classes. As useful as vector algebra is, it pales into insignificance when compared with the algebra that includes both kinds of arrays. It's my ultimate goal to describe a set of classes to support this algebra, so I'm anxious to complete the vector class.
The canonical set
Whenever I'm starting the development of a new class, I tend to start out with everything--declarations, definitions, and test driver--in a single file. That's a terrible way to write production code, but I like it for development because I don't have to change two or three files every time I change a definition. At this point, though, our class Vector has grown enough to justify a home of its own, in files of its own. I'm organizing those files now and will post them on Embedded.com at a later date. Instead, I want to concentrate on additions to the vector-class member functions.
When I was being taught object-oriented programming, I learned that every class should always contain the four functions:
- Default constructor
- Copy constructor
- Assignment operator
Even for classes that can get by with the compiler-generated forms for the default constructor and destructor, it's a good idea to include those functions.
The copy constructor is a constructor that creates a new copy of an existing object. For the class Vector, it looks like the code shown in Listing 1. The function vCopy( ) is one of the primitives from the file, SimpleVec.cpp. Its purpose should be obvious from the context. Here again, we have an issue of efficiency vs. simplicity and ease of use. Using a function like vCopy, however short it is, may seem extravagant, and perhaps it is, especially since we can accomplish the same thing with the library function, memcpy. I leave it to you to decide how best to implement the action.
The copy constructor isn't the only constructor we can add. We can include converting constructors as we choose, mapping other data types into vectors. In Listing 1, I've also shown two that I find useful: conversions from ordinary arrays and from a set of scalars. The latter constructor--specifically for building three-vectors--is pretty cool. I've given the third element, z, a default value of zero. This means I can use the constructor to manage vectors of only two dimensions. The vector will be converted to a 3-vector, whose third element happens to be zero.
Why is this useful? Well, consider the practical problem of computing the area of a polygon. A polygon is a plane figure, meaning its vertices can be expressed as a set of vectors in the x-y plane. In my October 2006 column ("Motivationally speaking," p.15) I showed you how we can compute the area as a sum of cross products.
But the cross-product operator is only defined for 3-vectors. The result of a cross product is not really a scalar, but another vector. If the two operands lie in the x-y plane, the resultant cross product ends up along the z-axis.