const_cast Operator
C++ provides the const_cast operator for casting away const or volatile qualification. A program declares a variable with the volatile qualifier when that program expects the variable to be modified by hardware or other programs not known to the compiler. Declaring a variable volatile indicates that the compiler should not optimize the use of that variable because doing so could affect the ability of those other programs to access and modify the volatile variable.
In general, it is dangerous to use the const_cast operator, because it allows a program to modify a variable that was declared const, and thus was not supposed to be modifiable. There are cases in which it is desirable, or even necessary, to cast away const-ness. For example, older C and C++ libraries might provide functions with non-const parameters and that do not modify their parameters. If you wish to pass const data to such a function, you would need to cast away the data's const-ness; otherwise, the compiler would report error messages.
Similarly, you could pass non-const data to a function that treats the data as if it were constant, then returns that data as a constant. In such cases, you might need to cast away the const-ness of the returned data, as we demonstrate in Fig. 24.1.
Figure 24.1. Demonstrating operator const_cast.
1 // Fig. 24.1: fig24_01.cpp 2 // Demonstrating const_cast. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include // contains prototypes for functions strcmp and strlen 8 #include // contains prototype for function toupper 9 10 // returns the larger of two C-style strings 11 const char *maximum( const char *first, const char *second ) 12 { 13 return ( strcmp( first, second ) >= 0 ? first : second ); 14 } // end function maximum 15 16 int main() 17 { 18 char s1[] = "hello"; // modifiable array of characters 19 char s2[] = "goodbye"; // modifiable array of characters 20 21 // const_cast required to allow the const char * returned by maximum 22 // to be assigned to the char * variable maxPtr 23 char *maxPtr = const_cast< char * >( maximum( s1, s2 ) ); 24 25 cout << "The larger string is: " << maxPtr << endl; 26 27 for ( size_t i = 0; i < strlen( maxPtr ); i++ ) 28 maxPtr[ i ] = toupper( maxPtr[ i ] ); 29 30 cout << "The larger string capitalized is: " << maxPtr << endl; 31 return 0; 32 } // end main
|
In this program, function maximum (lines 1114) receives two C-style strings as const char * parameters and returns a const char * that points to the larger of the two strings. Function main declares the two C-style strings as non-const char arrays (lines 1819); thus, these arrays are modifiable. In main, we wish to output the larger of the two C-style strings, then modify that C-style string by converting it to uppercase letters.
Function maximum's two parameters are of type const char *, so the function's return type also must be declared as const char *. If the return type is specified as only char *, the compiler issues an error message indicating that the value being returned cannot be converted from const char * to char *a dangerous conversion, because it attempts to treat data that the function believes to be const as if it were is non-const data.
Even though function maximum believes the data to be constant, we know that the original arrays in main do not contain constant data. Therefore, main should be able to modify the contents of those arrays as necessary. Since we know these arrays are modifiable, we use const_cast (line 23) to cast away the const-ness of the pointer returned by maximum, so we can then modify the data in the array representing the larger of the two C-style strings. We can then use the pointer as the name of a character array in the for statement (lines 2728) to convert the contents of the larger string to uppercase letters. Without the const_cast in line 23, this program will not compile, because you are not allowed to assign a pointer of type const char * to a pointer of type char *.
Error-Prevention Tip 24.1
In general, a const_cast should be used only when it is known in advance that the original data is not constant. Otherwise, unexpected results may occur. |