foc*_*ard 10 c++ dynamic-cast exception try-catch
我正在学习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;
}
Run Code Online (Sandbox Code Playgroud)
所以我认为try catch将允许函数执行并向我显示异常的内容,但我的编译器不会编译它.我正在使用GNU GCC的代码块.请帮助我,告诉我我需要做什么才能按照我的意图运行代码.非常感谢.
Cap*_*ous 18
dynamic_cast 只能转换为指针值或引用,这正是错误告诉你的.
从+ 5.2.7/1的C++标准.
表达式dynamic_cast <T>(v)的结果是将表达式v转换为类型T的结果.T应该是指向完整类类型的指针或引用,或者是"指向cv void的指针".
为了在dynamic_cast无法转换对象时抛出异常,您需要转换为引用.将其更改为以下内容:
dynamic_cast<AA&>(a).aa();
// ^^^ cast to reference.
Run Code Online (Sandbox Code Playgroud)
正如Johnsyweb指出的那样,当转换失败时,它dynamic_cast总会抛出std::bad_cast.虽然std::bad_cast从中得出std::exception它总是一个好主意,使用最符合预期失败条件的异常.这可以防止无意中将其他错误解释为不成功的强制转换.
要将此应用于您的示例,它可能看起来像下面的代码.
#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;
}
Run Code Online (Sandbox Code Playgroud)
[注意,using namespace std;强烈建议不要这样做,因为它可能会导致与全局命名空间中的标识符冲突.我在上面的例子中删除了它.]
您收到编译器错误,因为您dynamic_cast不在指针或引用上。
将其更改为:
dynamic_cast<AA&>(a).aa();
Run Code Online (Sandbox Code Playgroud)
...并且您会抛出正确的异常。
旁注:像 g++ 这样的智能编译器也会发出警告:
warning: dynamic_caston an object (here a) can never success。
因此最好限制此类代码的使用。在生产质量代码中,dynamic_cast应该仅对指针/引用执行。
您的问题不在于异常处理,而在于您的动态转换:
'AA' is not a reference or pointer
Run Code Online (Sandbox Code Playgroud)
dynamic_cast安全地将指针和引用转换为classes而不是实例.
所以你可以这样做:
dynamic_cast<AA&>(a).aa();
Run Code Online (Sandbox Code Playgroud)
... 总会失败并抛出std::bad_cast异常.
您应该捕获exception您期望的最具体类型,并且由于建议的方式catch是参考,您应该更喜欢:
catch (std::bad_cast const& ex)
Run Code Online (Sandbox Code Playgroud)
进一步阅读: cppreference.com上的dynamic_cast转换.
我刚刚处理了同样的错误,但就我而言,我是从指针到指针,所以这里的其他答案不适用。但是,我的错误消息略有不同:error: cannot dynamic_cast 'f()' (of type 'class B*') to type 'class A*' (target is not pointer or reference to complete type)。
我的案例的根本原因更加简单和平凡。
请注意最后添加了tocomplete 类型。这让我想起我没有包含我正在使用的类的头文件。它不是一个未知符号,因为A*是在头文件中向前声明的class A;,导致它存在但不完整,因此出现错误。
我的例子的解决方案是包含我要转换到的类的头文件。
这不是上面提问者的问题,但从我的案例可以看出,可以生成相同类型的错误。
| 归档时间: |
|
| 查看次数: |
20152 次 |
| 最近记录: |