C++ 错误:无法动态转换...(目标不是指针或引用)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17129728/
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
error: cannot dynamic_cast ... (target is not pointer or reference)
提问by focusHard
I'm learning exception handling in C++ and run into a problem. Here's the code:
我正在学习 C++ 中的异常处理并遇到问题。这是代码:
#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.
所以我认为 try catch 将允许函数执行并向我显示异常的内容,但我的编译器没有编译它。我在 GNU GCC 中使用代码块。请帮助我并告诉我我需要做什么才能使代码按预期运行。多谢。
回答by Captain Obvlious
dynamic_cast
can only cast to a pointer value or reference, which is exactly what the error is telling you.
dynamic_cast
只能转换为指针值或引用,这正是错误告诉您的。
From $5.2.7/1 of the C++ Standard.
从 C++ 标准 5.2.7/1 美元起。
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.”
表达式 dynamic_cast< T >(v) 的结果是将表达式 v 转换为类型 T 的结果。 T 应是指向完整类类型的指针或引用,或“指向 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
在对象无法转换时抛出异常,您需要转换为引用。将其更改为以下内容:
dynamic_cast<AA&>(a).aa();
// ^^^ cast to reference.
As Johnsywebpointed 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.
正如Johnsyweb指出的那样,转换失败时dynamic_cast
总是会抛出std::bad_cast
。尽管std::bad_cast
源自std::exception
它,但使用最适合预期失败条件的异常总是一个好主意。这可以防止无意中将其他错误解释为不成功的转换。
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.]
[注意,using namespace std;
强烈建议不要这样做,因为它会导致与全局命名空间中的标识符发生冲突。我已在上面的示例中将其删除。]
回答by Johnsyweb
Your problem is not with exception handling, but with your dynamic cast:
您的问题不在于异常处理,而在于您的动态转换:
'AA' is not a reference or pointer
dynamic_cast
safely converts pointersand referencesto class
es and not instances.
dynamic_cast
安全地将指针和引用转换为class
es 而不是实例。
So you could do:
所以你可以这样做:
dynamic_cast<AA&>(a).aa();
...which will alwaysfail and throw a std::bad_cast
exception.
...它总是会失败并抛出std::bad_cast
异常。
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:
您应该捕获exception
您期望的最具体的类型,并且由于推荐的方法catch
是 by reference,您应该更喜欢:
catch (std::bad_cast const& ex)
Further reading:dynamic_cast conversionon cppreference.com.
进一步阅读:cppreference.com上的dynamic_cast 转换。
回答by iammilind
You are getting a compiler error because your dynamic_cast
is not on pointer or reference.
Change it to:
您收到编译器错误,因为您dynamic_cast
不在指针或引用上。
将其更改为:
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.
旁注:像 g++ 这样的智能编译器也会发出警告:
warning: dynamic_cast
on an object (here a
) can never success。
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.
所以最好限制这样的代码来玩弄。在生产质量代码中,dynamic_cast
应该只在指针/引用上执行。
回答by Loduwijk
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)
.
我刚刚处理了同样的错误,但在我的情况下,我是从一个指针到一个指针,所以这里的其他答案不适用。但是,我的错误消息略有不同: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 typeat 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.
注意最后添加了to complete 类型。这让我想起我没有包含我正在使用的类的头文件。它不是未知符号,因为在头文件中使用了A*
向前声明class A;
,导致它存在但不完整,因此出现错误。
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.
这不是上面的提问者的问题,但从我的案例中可以看出可能会产生相同类型的错误。