| I l @ ve RuBoard |
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++
class
es. Actually, a structure is really just a data-only class with all the
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
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
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
C programmers also make use of the
struct a_struct { ... }
a_struct struct_var;
// ...
memset(&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. |
| I l @ ve RuBoard |
| I l @ ve RuBoard |
28.5 setjmp and longjmp
C has its own way of handling exceptions through the use of
setjmp
and
longjmp
. The
setjmp
function marks a place in a program. The
longjmp
function
Normally
setjmp
returns a zero. This
The definition of the setjmp function is: #include <setjmp.h> int setjmp(jmp_buf env); where env is the place where setjmp saves the current environment for later use by longjmp .
The
setjmp
function return values are as
The definition of the longjmp call is: void longjmp(jmp_buf env, int return_code);
where
env
is the environment
Figure 28-1 illustrates the control flow when using setjmp and longjmp . Figure 28-1. setjmp/longjmp control flow
There is one problem here, however. The
longjmp
call returns control to the corresponding
setjmp
.
It does not call the destructors of any classes that are "
In Figure 28-1 we can see that in the
subroutine
we define a class named
a_list
. Normally we would call the destructor for
a_list
at the end of the function or at a
return
statement. However, in this case we use
longjmp
to exit the function. Since
longjmp
is a C function, it
When converting C to C++, change all setjmp / longjmp combinations into exceptions. |
| I l @ ve RuBoard |