Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: "... is not a polymorphic type" while using boost::dynamic_pointer_cast

Tags:

Why do I receive the following error for the following code?

1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(259): error C2683: 'dynamic_cast' : 'my_namespace::A' is not a polymorphic type 1>          D:\[location]\[header_filename].h(35) : see declaration of 'my_namespace::A' 1>          C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(522) : see reference to function template instantiation 'boost::shared_ptr<T>::shared_ptr<my_namespace::A>(const boost::shared_ptr<my_namespace::A> &,boost::detail::dynamic_cast_tag)' being compiled 1>          with 1>          [ 1>              T=my_namespace::B 1>          ] 1>          [location]\[source_filename].cpp(217) : see reference to function template instantiation 'boost::shared_ptr<T> boost::dynamic_pointer_cast<my_namespace::B,striker::A>(const boost::shared_ptr<my_namespace::A> &)' being compiled 1>          with 1>          [ 1>              T=my_namespace::B 1>          ] 1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(260): fatal error C1903: unable to recover from previous error(s); stopping compilation 

The C++ code is more or less the following:

#include <list> #include "boost/pointer_cast.hpp" #include "boost/shared_ptr.hpp"  struct A { public:     A(const MyEnum an_enum_, const int an_int_) :         an_enum(an_enum_),         an_int(an_int_)     {}      const MyEnum an_enum;     const int an_int; };  struct B : public A { public:     B(const int some_int_, const MyStruct &a_struct_) :         A(ENUM_OPTION_A, an_int_),         a_struct(a_struct_)     {}      const MyStruct a_struct; };   // Ussage in some function: // ... boost::shared_ptr<A> a_ptr = boost::shared_ptr<A>( new B() ); std::list<boost::shared_ptr<A>> a_list; a_list.push_back(a_ptr); // ... boost::shared_ptr<A> a_ptr2 = a_list.front(); boost::shared_ptr<B> b_ptr = boost::dynamic_pointer_cast<B>(a_ptr2); // <-- error here // ... 
like image 403
Jonathan Livni Avatar asked Apr 29 '11 12:04

Jonathan Livni


1 Answers

dynamic_cast works ONLY with polymorphic class. And polymorphic class is that which has atleast one virtual function, even be it the destructor.

//polymorphic classes struct A {    virtual ~A(); //even virtual destructor makes a class polymorphic! }; struct B : A {    void f(); };  //non-polymorphic classes     struct C {    ~C(); //not virtual };  struct D : C {    void f(); //not virtual either }; 

In the above code, A and B are polymorphic classes, but C and D are not.

A *pA = new B(); B *pB = dynamic_cast<B*>(pA); //okay  C *pC = new D(); D *pD = dynamic_cast<D*>(pC);  //error -  not polymorphic class 

Note that in dynamic_cast, only the source type need to be polymorphic in order to compile. If the destination isn't polymorphic, then dynamic_cast will return null pointer.

D *pD = dynamic_cast<D*>(pA);  //okay - source (pA) is polymorphic  if ( pD )         cout << "pD is not null" ; else        cout << "pD is null"; 

Output:

pD is null 

Online demo: https://web.archive.org/web/20000000000000/http://www.ideone.com/Yesxc

like image 187
Nawaz Avatar answered Sep 18 '22 17:09

Nawaz