28.4
Turning Structures into Classes
Frequently when examining C code you may find a number of defined
struct statements that look like they should be
objects defined as C++ classes. Actually, a
structure is really just a data-only class with all the members
public.
C programmers frequently take advantage of the fact that a structure
contains only data. One example of this is reading and writing a
structure to a binary file. For example:
a_struct struct_var; // A structure variable
// Perform a raw read to read in the structure
read_size = read(fd, (char *)&struct_var, sizeof(struct_var));
// Perform a raw write to send the data to a file
write_size = write(fd, (char *)&struct_var, sizeof(struct_var));
Turning a structure like this into a class can cause problems. C++
keeps extra information, such as virtual function pointers, in a
class. When you write the class to disk using a raw write, you are
outputting all that information. What's worse, when
you read the class in, you overwrite this bookkeeping data.
For example, suppose we have the class:
class sample {
public:
const int sample_size; // Number of samples
int cur_sample; // Current sample number
sample( ) : sample_size(100) {} // Set up class
virtual void get_sample( ); // Routine to get a sample
};
Internally, this class consists of
three member variables: a constant,
sample_size (which C++ won't
allow you to change); a simple variable,
cur_sample; and a pointer to the real function to
be used when get_sample is called. All three of
these are written to disk by the call:
sample a_sample;
// ...
write_size = write(fd, (char *)&a_sample, sizeof(a_sample));
When this class is read, all three members are
changed. That includes the constant (which we aren't
supposed to change) and the function pointer (which now probably
points to something strange).
C programmers also make use of the memset function
to set all the members of a structure to zero. For example:
struct a_struct { ... }
a_struct struct_var;
// ...
memset(&struct_var, '\0', sizeof(struct_var));
Be careful when turning a structure into a class. If we had used the
class a_sample in the previous example instead of
the structure struct_var, we would have zeroed the
constant sample_size as well as the virtual
function pointer. The result would probably be a crash if we ever
tried to call get_sample.
|