错误:不能dynamic_cast ...(目标不是指针或引用)

时间:2013-06-16 02:48:24

标签: c++ exception try-catch dynamic-cast

我正在学习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;
}

所以我认为try catch将允许函数执行并向我显示异常的内容,但是我的编译器没有编译它。我正在使用GNU GCC的代码块。请帮助我,告诉我我需要做什么才能按照我的意图运行代码。非常感谢。

4 个答案:

答案 0 :(得分:18)

dynamic_cast只能转换为指针值或引用,这正是错误告诉你的。

来自C ++标准的5.2.7 / 1美元。

  

表达式dynamic_cast&lt;的结果T>(v)是将表达式v转换为类型T的结果.T应该是指向完整类类型的指针或引用,或者是“指向cv void的指针”。

为了使dynamic_cast在无法转换对象时抛出异常,您需要转换为引用。将其更改为以下内容:

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

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;
}

[注意,强烈建议不要使用using namespace std;这样的操作,因为它可能会导致与全局命名空间中的标识符冲突。我在上面的示例中删除了它。]

答案 1 :(得分:5)

您的问题不在于异常处理,而在于动态广告

'AA' is not a reference or pointer

dynamic_cast安全地将指针引用转换为class es而非实例

所以你可以这样做:

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

... 总是失败并抛出std::bad_cast例外。

您应该抓住您期望的最具体的exception类型,而the recommended way to catch is by reference,您应该更喜欢:

catch (std::bad_cast const& ex)

dynamic_cast conversion上进一步阅读 cppreference.com

答案 2 :(得分:4)

您收到编译错误,因为您的dynamic_cast不在指针或引用上 将其更改为:

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

...你得到了正确的异常抛出。

侧面说明:像g ++这样的智能编译器也会发出警告:
警告:dynamic_cast对象(此处a)永远无法成功

所以最好限制这些代码来玩弄。在生产质量代码中,dynamic_cast应仅在指针/引用上执行。

答案 3 :(得分:3)

我刚刚处理了同样的错误,但在我的情况下,我是从指针指向指针,所以这里的其他答案不适用。我的错误消息略有不同,但是:error: cannot dynamic_cast 'f()' (of type 'class B*') to type 'class A*' (target is not pointer or reference to complete type)

在我的案例中,根本原因更为简单和平凡。

注意最后添加以完成类型。这让我记住我没有包含我正在使用的类的头文件。它不是一个未知的符号,因为A*在头文件中使用class A;向前声明,导致它存在但不完整,因此错误。

我的解决方案是包含我正在投射的类的头文件。

这不是上面的问题提问者,但我的情况可以看出可以产生相同类型的错误。