Next: Cloning Objects
Up: Some Not So Useful
Previous: Getting an Object's Type
  Contents
As discussed previously, each GAT class has a corresponding ``Equals'' function. In this subsection we
will examine this ``Equals'' function.
First one may wonder what such an ``Equals'' function actually does as C is equipped with a extreemely
useful ==. As GATObject instances are opaque pointers, one can use the == with
which C is equipped to determine the equality of two such GATObject instances. For example, if
we had two GATTime instances, timeOne and timeTwo, then we could determine
their equality as follows
if( timeOne == timeTwo )
{
printf("timeOne == timeTwo");
}
This would determine if the two opaque pointers timeOne and timeTwo point to the
same region in memory, a useful piece of knowledge. However, it is often not enough.
There exist at least two notions of equivalence one commonly deals with: pysical equivalence, illustrated
by the previous example using ==, and semantic equivalence, which is what the ``Equals'' functions
implement. For example, two GATTime instances are semantically equivalent if they currespond to the
same number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC, the epoch. However, this semantic
equivalence need not imply physical equivalence, which would only occur if the two instances
are found to be equivalent using ==.
The example for this section will hopefully clarify these concepts. The full example is as follows
#include "GAT.h"
#include <stdio.h>
int main(void)
{
GATBool isequal;
GATTime timeOne;
GATTime timeTwo;
GATResult result;
/* Create a GATTime corresponding to 1 hour after the epoch */
timeOne = GATTime_Create( 3600 );
/* Create a GATTime corresponding to 1 hour after the epoch */
timeTwo = GATTime_Create( 3600 );
/* Determine physical equivalence of timeOne and timeTwo */
if( timeOne == timeTwo )
{
printf( "timeOne and timeTwo are physically equivalent\n" );
}
else
{
printf( "timeOne and timeTwo are not physically equivalent\n" );
}
/* Determine semantic equivalence of timeOne and timeTwo */
if( (NULL != timeOne) && (NULL != timeTwo) )
{
result = GATTime_Equals( timeOne, timeTwo, &isequal );
if( GAT_SUCCEEDED( result ) )
{
if( GATTrue == isequal )
{
printf( "timeOne and timeTwo are semantically equivalent\n" );
}
else
{
printf( "timeOne and timeTwo are not semantically equivalent\n" );
}
}
}
/* Destroy the GATTime timeOne */
GATTime_Destroy( &timeOne );
/* Destroy the GATTime timeTwo */
GATTime_Destroy( &timeTwo );
return 0;
}
Let us examine this program.
The lines
#include "GAT.h"
#include <stdio.h>
int main(void)
{
...
}
are now standard. They include the required GAT header GAT.h, the standard C header stdio.h, and
the standard main function. The next lines
GATBool isequal;
GATTime timeOne;
GATTime timeTwo;
GATResult result;
declare the variable isequal of type GATBool, a type covered in Appendix ,
the variable timeOne and timeTwo, each of type GATTime, and result, a variable of
type GATResult. The type GATResult is simply typedef'd to be the GAT primitive type
GATint32. Variables of type GATResult are used to return the completion status of a function. Various
completion statuses correspond to various GATResult values. The various values and the semantics of
the various values will not be covered here as that would take us a bit far afield; however, in Appendix
the various values and their semantics are covered in detail. The next lines
/* Create a GATTime corresponding to 1 hour after the epoch */
timeOne = GATTime_Create( 3600 );
/* Create a GATTime corresponding to 1 hour after the epoch */
timeTwo = GATTime_Create( 3600 );
create two GATime instances each corresponding to seconds after the epoch. The following lines
/* Determine physical equivalence of timeOne and timeTwo */
if( timeOne == timeTwo )
{
printf( "timeOne and timeTwo are physically equivalent\n" );
}
else
{
printf( "timeOne and timeTwo are not physically equivalent\n" );
}
determine if the two instances, timeOne and timeTwo, are physically equivalent and print
the result of this determination. What will it print? The next lines
/* Determine semantic equivalence of timeOne and timeTwo */
if( (NULL != timeOne) && (NULL != timeTwo) )
{
result = GATTime_Equals( timeOne, timeTwo, &isequal );
if( GAT_SUCCEEDED( result ) )
{
if( GATTrue == isequal )
{
printf( "timeOne and timeTwo are semantically equivalent\n" );
}
else
{
printf( "timeOne and timeTwo are not semantically equivalent\n" );
}
}
}
first check that timeOne and timeTwo are both not NULL. They then call the function
GATResult GATTime_Equals( GATTime timeOne, GATTime timeTwo, GATBool *isequal )
This function determines if the passed GATTime instances, timeOne and timeTwo, are semantically
equivalent. It returns the result of this determination in the GATBool pointed to by the passed GATBool*.
The completion status of this function is returned through the return value of this function, a GATResult.
The next lines
if( GAT_SUCCEEDED( result ) )
{
...
}
check that the call to the function GATTime_Equals completed sucessfully through use of the macro
GAT_SUCCEEDED. Use of this macro is covered in Appendix . The
next lines
if( GATTrue == isequal )
{
printf( "timeOne and timeTwo are semantically equivalent\n" );
}
else
{
printf( "timeOne and timeTwo are not semantically equivalent\n" );
}
check the value of isequal against GATTrue and print out the result of this comparison.
If isequal has value GATTrue, then timeOne and timeTwo are semantically
equivalent. If isequal does not have value GATTrue, then timeOne and timeTwo
aren't semantically equivalent. What will this print? The final lines of the program
/* Destroy the GATTime timeOne */
GATTime_Destroy( &timeOne );
/* Destroy the GATTime timeTwo */
GATTime_Destroy( &timeTwo );
return 0;
simply clean up the allocated GATTime instances and return from the main function.
Next: Cloning Objects
Up: Some Not So Useful
Previous: Getting an Object's Type
  Contents
Andre Merzky
2004-05-13
|