advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
std::string has been around for 10 years or so. In retrospect, do you think that the decision not to include a const char * conversion operator was right, considering that many functions in the Standard Library still use char * exclusively? Let us know in the C++ Developer Forum.
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Rate this item | 0 users have rated this item.
Preserve Code Safety with Conversion Operators (cont'd)
Declaring Constructors 'explicit'
To correct this flaw, first declare the constructor explicit:

class USD
{
public:
explicit USD(__int64 d=0, int c=0):
dollars(d), cents(c){}
...
advertisement
This way, only assignments of USD objects will be accepted:

payment=USD(payment*1.05); //fine
payment=payment*1.05; //compilation error
Adding another Constructor
The second fix is to add another constructor that takes an argument of type double:

class USD
{
public:
explicit USD(double val)
{
dollars=val; //copy the integral part
long double temp=(val-dollars)*100; //extract cents
//avoid truncation e.g., .6699 to 66 rather than 67
cents=temp+0.5;
}
};
Here again, the constructor is declared 'explicit' to avoid inadvertent assignments. To increase payment by 5 percent, use the following form instead:

payment=USD(payment*1.05);
Now, everything's in order. Inadvertent conversions by a promiscuous constructor are blocked, whereas well-behaved conversions to double that rely on the conversion operator are permitted.

Better Safe than Sorry
Programmers often moan about the lack of a const char * conversion operator in class std::string. If std::string had such an operator, you could write


string filename;
ifstream inf(filename);
Instead of the ugly:

ifstream inf(filename.c_str());
However, the C++ standardization committee decided not to include a conversion operator of this kind in std::string because it might cause nasty bugs in certain libraries in which char * are used extensively. In this case, the committee adhered to the "better safe than sorry" idiom. By contrast, <fstream> objects contain a conversion operator to type void* which enables you to use them like this:

ifstream inf("myfile");
if (inf) //using void * conversion operator
//use the file
else
//failure
When you design your own classes, consider which automatic conversions are desirable and which ones should be disabled. Then, enable legitimate conversions by defining the appropriate conversion operators while blocking undesirable conversions by declaring constructors explicit.
Previous Page: Demonstrating the Problem  
Danny Kalev is a system analyst and software engineer with 13 years of experience, specializing in C++ and object-oriented analysis and design. He is a member of the ANSI C++ standardization committee and the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999, ISBN: 0789720221).
Page 1: IntroductionPage 3: Declaring Constructors 'explicit'
Page 2: Demonstrating the Problem 
Please rate this item (5=best)
 1  2  3  4  5
advertisement