C++:使用 boost::dynamic_pointer_cast 时“...不是多态类型”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5831765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:57:31  来源:igfitidea点击:

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

c++compiler-errorsshared-ptrdynamic-cast

提问by Jonathan

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:

C++ 代码或多或少如下:

#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
// ...

回答by Nawaz

dynamic_castworks ONLY with polymorphic class. And polymorphicclass is that which has atleast one virtualfunction, even be it the destructor.

dynamic_cast仅适用于多态类。而polymorphic类是具有ATLEAST一个virtual功能,即使是它的析构函数。

//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, Aand Bare polymorphic classes, but Cand Dare not.

在上面的代码中,AB是多态类,但CD不是。

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 polymorphicin order to compile. If the destination isn't polymorphic, then dynamic_castwill return null pointer.

请注意,在 中dynamic_cast,只有源类型需要多态才能编译。如果目标不是polymorphicdynamic_cast则将返回空指针。

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

在线演示:https://web.archive.org/web/20000000000000/http: //www.ideone.com/Yesxc

回答by Alexander Gessler

'dynamic_cast' : 'my_namespace::A' is not a polymorphic typebecause it doesn't define or inherit a single virtualfunction. Just add a virtual destructor and you'll be fine.

'dynamic_cast' : 'my_namespace::A' is not a polymorphic type因为它没有定义或继承单个virtual函数。只需添加一个虚拟析构函数就可以了。

dynamic_castworks only for such 'polymorphic' types.

dynamic_cast仅适用于此类“多态”类型。

回答by sharptooth

struct Ahas no virtual methods (not even a destructor), so you can't dynamic_castfrom A*- only pointers to types with at least one virtual member function can be used dynamic_caston. boost::dynamic_pointer_castdoes dynamic_castinside, to it's subject to same requirements.

struct A不具有虚拟方法(甚至没有析构函数),所以不能dynamic_castA*-仅指针类型的具有至少一个虚拟成员函数,可以使用dynamic_cast上。boost::dynamic_pointer_castdynamic_cast里面,它受到相同的要求。