TITLE: less evil situations for casting PROBLEM: ntsivran@bach.fmrco.com (Nick Tsivranidis) [...] if you need casting there is a pretty good chance you've got something wrong in the design phase. RESPONSE: thant@interramp.com (Thant Tessman) Yes, explicit casts are evil. But there are two places where I haven't been able to get around them. The first is when a member function is semantically constant but actually does some sort of memoization/caching. In that case I cast the `this' pointer to a pointer to a non-constant object. The second case is when I'm doing my own memory management, for example in my dynamic array template. I challenge anyone to convince me that either of these cases are the product of design flaws--other than in C++ itself, that is. [ The language has a capability to tag data members as "cached" values, ie changeable even when the enclosing object is const. This is specified with the mutable keyword (not yet supported in many compilers). -adc ] RESPONSE: wolfe!resrch!janr@uunet.uu.net (Jan Reimers) This "rule of thumb" always bothers me. I often encounter situations where a pair of objects derived from the same base have to communicate. I find that in these situations using RTTI results in BETTER OO design, than other popular solutions. [example of Visitor pattern (double dispatch) and constrasting use of dynamic_cast elided] So by using RTTI one maintains a stable interface which is the goal of OOD. The RTTI solution is also safer, there is no requirement that the programmer remeber to implement the "double dispatch" functions in each derived class. [ RTTI is "run time type identification" -adc ] RESPONSE: rmartin@oma.com (Robert C. Martin), 19 Dec 95 There is a simple rule of thumb with regard to RTTI. If you use RTTI in a context that must change when new derived classes are created, then you have misused it. If, OTOH, you use RTTI in a context that will remain stable when new derived classes are added, you have used it appropriately. Jan's example of operator== is classic: bool Derived::operator==(const Base& b) { bool equal = false; if (typeid(*this) == typeid(b)) // make sure types are the same { Derived& d = static_cast(b); // cast is safe // now compare like objects. } return equal; } This use of RTTI will be unaffected by any new derivatives of Base, and is therefore perfectly safe and not indicative of "bad design". On the other hand a use of the following kind: bool Shape::IsReqular() { if (typeid(*this) == typeid(Square)) return true; if (typeid(*this) == typeid(Circle)) return true; return false; }; This use of RTTI is insidious since it must be reexamined every time a new derivative of Shape is created. For some new derivatives it may need to be modified, for others it can be left unchanged. This violates the open/closed principle (Bertrand Meyer, Object Oriented Software Construction, Prentic Hall) and causes the class Shape, and every class that depends upon Shape, including all its derivatives, to be affected every time a new derivative of shape is added.