error: cannot dynamic_cast … (target is not pointer or reference)

拥有回忆 提交于 2019-12-10 01:54:49

问题


I'm learning exception handling in C++ and run into a problem. Here's the code:

#include<iostream>
#include<exception>

using namespace std;

class A
{
public:
    virtual void f(void){}
};

class AA:public A
{
public:
    void aa(void){};

};

int main(void)
{

    A a;
    try
    {
        dynamic_cast<AA>(a).aa();
    }
    catch(exception ex)
    {
        cout<<"["<<ex.what()<<"]"<<endl;
    }
    return 0;
}

So I thought the try catch will allow the function to execute and show me the content of the exception, but my compiler does not compile it. I'm using codeblock with GNU GCC. Please help me and show me what I need to do to get the code run as I intended. thanks a lot.


回答1:


dynamic_cast can only cast to a pointer value or reference, which is exactly what the error is telling you.

From $5.2.7/1 of the C++ Standard.

The result of the expression dynamic_cast< T >(v) is the result of converting the expression v to type T. T shall be a pointer or reference to a complete class type, or “pointer to cv void.”

In order for dynamic_cast to throw an exception when the object cannot be converted you need to cast to a reference. Change it to the following:

dynamic_cast<AA&>(a).aa();
//           ^^^ cast to reference.

As Johnsyweb pointed out dynamic_cast will always throw std::bad_cast when the conversion fails. Although std::bad_cast is derived from std::exception it is always a good idea to use the exception which best fits the expected fail condition. This prevents inadvertently interpreting other errors as an unsuccessful cast.

To apply this to your example it might look like the code below.

#include <iostream>
#include <typeinfo> // std::bad_cast

class A
{
public:
    virtual void f(void){}
};

class AA:public A
{
public:
    void aa(void){};
};

int main(void)
{
    A a;

    try
    {
        dynamic_cast<AA&>(a).aa();
    }
    catch(const std::bad_cast& ex)
    {
        std::cout << "["<<ex.what()<<"]" << std::endl;
    }
    return 0;
}

[Note, doing things like using namespace std; is strongly discouraged as it can cause conflicts with identifiers in the global namespace. I have removed it in the example above.]




回答2:


Your problem is not with exception handling, but with your dynamic cast:

'AA' is not a reference or pointer

dynamic_cast safely converts pointers and references to classes and not instances.

So you could do:

dynamic_cast<AA&>(a).aa();

...which will always fail and throw a std::bad_cast exception.

You should catch the most-specific type of exception that you are expecting and since the recommended way to catch is by reference, you should prefer:

catch (std::bad_cast const& ex)

Further reading: dynamic_cast conversion on cppreference.com.




回答3:


You are getting a compiler error because your dynamic_cast is not on pointer or reference.
Change it to:

dynamic_cast<AA&>(a).aa();

... and you get the proper exception thrown.

On side note: Smart compilers like g++ would warn as well:
warning: dynamic_cast on an object (here a) can never succeed.

So it's better to limit such code for toying around. In production quality code, the dynamic_cast should be performed only on pointer/reference.




回答4:


I just dealt with the same error, but in my case I was going from a pointer to a pointer, so the other answers here did not apply. My error message was slightly different, however: error: cannot dynamic_cast 'f()' (of type 'class B*') to type 'class A*' (target is not pointer or reference to complete type).

The root cause in my case was much more simple and mundane.

Notice the addition of to complete type at the end. This caused me to remember that I did not include the header file for my class which I was using. It was not an unknown symbol because A* was forward declared with class A; in the header file, causing it to exist but not be complete, hence the error.

The solution in my case was to include the header file for the class I was casting to.

This is not the question asker's problem above, but as can be seen by my case can generate the same type of error.



来源:https://stackoverflow.com/questions/17129728/error-cannot-dynamic-cast-target-is-not-pointer-or-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!