Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Restrain Conversion Operators with the "Indirect Conversion" Idiom-4 : Page 4


advertisement
Smooth Operator
Let's analyze the return statement. If rawptr isn't NULL, the conversion operator returns a pointer to a member of struct PtrConversion (the precise value of the expression &PtrConversion::valid is immaterial; what matters is that it's a non-NULL constant). However, if rawptr is NULL, the conversion operator returns a NULL pmi. Recall that all pointers to members are implicitly convertible to bool; they aren't bool variables, though. This subtle difference is crucial, as you will see.

After this change, when the following statement executes:

if(ptr) //...

C++ calls ptr.operator pmi() behind the scenes. The return value of type pmi is then silently converted to bool, as expected. However, the following statement no longer compiles, which is exactly what you want:


cout<<"p1 + p2 = "<< p1+p2 <<endl; //compilation error

Here's the secret: C++ guarantees that an operand shall undergo at most one implicit conversion. In the if(ptr) example, you have exactly one implicit conversion from pmi to bool (the very invocation of a conversion operator doesn't constitute an implicit conversion for this matter). However, in the expression p1+p2 two implicit conversions per operand are necessary:
  1. pmi—>bool
  2. bool—>int
As I said, C++ doesn't allow this.

Let's see how this technique eliminates the problems caused by a void* conversion operator:

cout << pf <<endl; //now a compilation error

This statement no longer compiles since there is no overloaded version of operator << that takes pmi or Ptr<T>. Similarly, the following delete expression:

delete pf; //compilation error

doesn't compile because neither pmi nor bool are valid types in a delete expression.

Twisting by the bool
The boost::shared_ptr class uses a slightly different version of the indirect conversion technique. Instead of using a dummy nested struct, it uses a pointer to a member of class shared_ptr itself. In terms of memory footprint, there is no difference between the two versions because the dummy struct is not instantiated anyway. However, some compilers have difficulties coping with pointers to member functions of a class template so the Boost library uses conditional compilation to switch between a pointer to a data member and a pointer to a member function as the target type of the Boolean conversion operator. The bottom line is this: instead of bool, void* or int as the target type of a Boolean conversion operator, use a pointer to member to minimize the perils of implicit conversions.



Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap