|  | Home | Libraries | People | FAQ | More | 
      Pointers to polymorphic objects (objects of classes which define at least one
      virtual function) are sometimes downcast or crosscast. Downcasting means casting
      from a base class to a derived class. Crosscasting means casting across an
      inheritance hierarchy diagram, such as from one base to the other in a Y
      diagram hierarchy.
    
Such casts can be done with old-style casts, but this approach is never to be recommended. Old-style casts are sorely lacking in type safety, suffer poor readability, and are difficult to locate with search tools.
        The C++ built-in static_cast
        can be used for efficiently downcasting pointers to polymorphic objects,
        but provides no error detection for the case where the pointer being cast
        actually points to the wrong derived class. The polymorphic_downcast
        template retains the efficiency of static_cast
        for non-debug compilations, but for debug compilations adds safety via an
        assert()
        that a dynamic_cast succeeds.
      
        A polymorphic_downcast should
        be used for downcasts that you are certain should succeed. Error checking
        is only performed in translation units where NDEBUG
        is not defined, via
      
assert( dynamic_cast<Derived>(x) == x )
        where x is the source pointer.
        This approach ensures that not only is a non-zero pointer returned, but also
        that it is correct in the presence of multiple inheritance. Attempts to crosscast
        using polymorphic_downcast
        will fail to compile.
      
| ![[Warning]](../../../doc/src/images/warning.png) | Warning | 
|---|---|
| 
          Because  | 
#include <boost/polymorphic_cast.hpp> ... class Fruit { public: virtual ~Fruit(){}; ... }; class Banana : public Fruit { ... }; ... void f( Fruit * fruit ) { // ... logic which leads us to believe it is a Banana Banana * banana = boost::polymorphic_downcast<Banana*>(fruit); ... }
        The C++ built-in dynamic_cast
        can be used for downcasts and crosscasts of pointers to polymorphic objects,
        but error notification in the form of a returned value of 0 is inconvenient
        to test, or worse yet, easy to forget to test. The throwing form of dynamic_cast, which works on references, can
        be used on pointers through the ugly expression &dynamic_cast<T&>(*p), which
        causes undefined behavior if p
        is 0. The polymorphic_cast
        template performs a dynamic_cast
        on a pointer, and throws an exception if the dynamic_cast
        returns 0.
      
        For crosscasts, or when the success of a cast can only be known at runtime,
        or when efficiency is not important, polymorphic_cast
        is preferred.
      
        The C++ built-in dynamic_cast
        must be used to cast references rather than pointers. It is also the only
        cast that can be used to check whether a given interface is supported; in
        that case a return of 0 isn't an error condition.
      
        While polymorphic_downcast
        and polymorphic_cast work
        with built-in pointer types only, polymorphic_pointer_downcast
        and polymorphic_pointer_cast
        are more generic versions with support for any pointer type for which the
        following expressions would be valid:
      
        For polymorphic_pointer_downcast:
      
static_pointer_cast<Derived>(p); dynamic_pointer_cast<Derived>(p);
        For polymorphic_pointer_cast:
      
dynamic_pointer_cast<Derived>(p); !p; // conversion to bool with negation
        This includes C++ built-in pointers, std::shared_ptr,
        boost::shared_ptr, boost::intrusive_ptr,
        etc.
      
#include <boost/polymorphic_pointer_cast.hpp> class Fruit { public: virtual ~Fruit(){} }; class Banana : public Fruit {}; // Use one of these: typedef Fruit* FruitPtr; typedef std::shared_ptr<Fruit> FruitPtr; typedef boost::shared_ptr<Fruit> FruitPtr; typedef boost::intrusive_ptr<Fruit> FruitPtr; void f(FruitPtr fruit) { // ... logic which leads us to believe it is a banana auto banana = boost::polymorphic_pointer_downcast<Banana>(fruit); ... }