C ++ dynamic_cast异常

时间:2015-11-25 13:47:11

标签: c++ exception inheritance virtual dynamic-cast

请帮助我理解奇怪的行为:

我在处理析构函数MyObject时使用MyLogicObject~MyLogicObject()的dynamic_cast,但编译器抛出异常:non_rtti_object

我确定对象MyObject是多态类型。我哪里错了?

#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <string>

class A
{
    int a;
};

class B
{
    int b;
};

class MyObject: public A,
                public B// if comment this row, and don't use multi inheritable, everything will be fine
{
    private: std::string name;
    private: bool singleshot;


    public: MyObject(void);

    public: virtual ~MyObject(void);

    protected: void Destroying(void);

    public: std::string GetName(void);

    public: virtual bool Rename(std::string _newName);
};

#endif

#include "MyObject.h"
#include "MyLogicObject.h"

MyObject::MyObject(void): singleshot(true)
{}


MyObject::~MyObject(void)
{
    printf("\n~my object\n");
    Destroying();
}


void MyObject::Destroying(void)
{
    if(singleshot)
    { 
        printf("\nexception!\n");
        dynamic_cast<MyLogicObject*>(this);// exception: non_rtti_object
        singleshot = false;
    }
}


std::string MyObject::GetName(void)
{
    return name;
}


bool MyObject::Rename(std::string _newName)
{
    name = _newName;
    return true;
}


#ifndef MYLOGICOBJECT_H
#define MYLOGICOBJECT_H
#include "MyObject.h"

    class MyLogicObject: public virtual MyObject // if not use virtual  inheritance (instead, use the standard inheritance), everything will be fine
    {
        public: MyLogicObject(void);

        public: virtual ~MyLogicObject(void);

        public: virtual void Update(float _delta = 0.0f);

        // if reimplement virtual method of base class, everything will be fine
        /*
        public: virtual bool Rename(std::string _newName)
        {
            return MyObject::Rename(_newName);
        }
        */ 
    };

    #endif 

#include "MyLogicObject.h"


MyLogicObject::MyLogicObject(void)
{}


MyLogicObject::~MyLogicObject(void)
{
    printf("\n~my logic object\n");
    Destroying();
}



void MyLogicObject::Update(float _delta)
{}

#include <conio.h>
#include <stdio.h>
#include "MyLogicScene.h"


class C
{
    int c;
};



class DerivedObject: public MyLogicObject,
                     public C// if comment this row, and don't use multi inheritable, everything will be fine
{
    public: DerivedObject(void)
    {}

    public: virtual ~DerivedObject(void)
    {
        printf("~derived object: %s\n", GetName().c_str());
        //Destroying(); // if call Destroying in this place, overything will be file
    }
};


int main()
{
    DerivedObject* object1 = new DerivedObject();
    object1->Rename("object1");

    printf("delete object1...\n");
    delete object1;


    getch();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

您正尝试将基类(MyObject)类型的对象动态转换为派生类(MyLogicObject)。除非基类是多态的并且启用了rtti,否则不允许使用dynamic_cast进行此转换。请参阅this以供参考。

所以你基本上需要在你的编译器选项中启用rtti。 完成后,确保object1是派生类(MyLogicObject)的完整对象,以便在不引发异常的情况下执行转换。

它也适用于相反的情况。例如,如果您尝试将派生类(MyLogicObject)类型的对象动态转换为基类(MyObject)。