// // void-ptr-example.cc // Sample program illustrating the use of enums and void* // #include #include using namespace std; // This line is necessary when using the STL // An enum is a user-defined type that has a finite number of possible values // (for instance, the "Type" enum has only three possible values). The // compiler will silently replace each enum value with an integer, which // means you get all the benefits of #define's *and* type safety too! enum Type { INTEGER, DOUBLE, STRING, }; struct Data { void *pData; // A void pointer is a pointer to data of // arbitrary type Type dataType; // This enum will tell me what is the type of the // data stored in pData }; int main( void ) { char input = 'a'; // Initialize it to something so we can get into // the while-loop Data arr[ 100 ]; // Make an array of 100 'Data' structs int size = 0; // Array index int i; // Temporary variables to store the user's input double d; char s[ 100 ]; // // Get input from the user and put it in the array // while( input != '0' ) { // Ask the user what is the type of the data they'll be putting in cout << " Data type ('i' = int, 'd' = double," << " 's' = string, '0' = print): "; cin >> input; // Figure out what data type they want to enter, and get their data cout << " Data: "; if( input == 'i' ) { // The user wants to enter an int // We can store int pointers in void pointers! cin >> i; arr[ size ].pData = new int( i ); arr[ size ].dataType = INTEGER; size++; } else if( input == 'd' ) { // The user wants to enter a double // We can store double pointers in void pointers, too! cin >> d; arr[ size ].pData = new double( d ); arr[ size ].dataType = DOUBLE; size++; } else if( input == 's' ) { // The user wants to enter a string // Get rid of extraneous newlines char newLine; cin >> newLine; if( newLine != '\n' ) { cin.putback( newLine ); } // We can store pointers to classes in void // pointers, naturally cin.getline( s, 100 ); arr[ size ].pData = new string( s ); arr[ size ].dataType = STRING; size++; } // Don't do anything if they user gave us bad input or if // they want to quit } cout << endl; // // Now that we've got an array of void pointers, let's loop // through it and print out the user's data. This is where // the Type enum comes in -- it allows us to know what is // the type of the data the void* is pointing at. // // Remember, we must cast a void* before we can // dereference it. // for( int index = 0; index < size; index++ ) { if( arr[ index ].dataType == INTEGER ) { cout << "Integer, value " << *( (int *) arr[ index ].pData ) << endl; delete (int *) arr[ index ].pData; // Clean up our dynamic memory } else if( arr[ index ].dataType == DOUBLE ) { cout << "Double, value " << *( (double *) arr[ index ].pData ) << endl; delete (double *) arr[ index ].pData; // Clean up our dynamic memory } else if( arr[ index ].dataType == STRING ) { cout << "String, value " << *( (string *) arr[ index ].pData ) << endl; delete (string *) arr[ index ].pData; // Clean up our dynamic memory } // If the Type of the data is unrecognized, then we defintely don't // want to guess what it is! Just leave it alone } return 0; }