检测继承类并将其转换为基类

Detecting and Converting inheritance class to base class

本文关键字:转换 基类 继承 检测      更新时间:2023-10-16

我有3个类,一个是基类,其他是从基类继承的类,下面是类的代码:

// Event Class
#ifndef EVENT_H
#define EVENT_H
#include <iostream>
namespace Engine
{
    namespace Data
    {
        // base class
        class Event
        {
            public:
                // Class Variable
                int Measure;
                int Beat;
                int Position;
                // This Class that was I mean
                class SampleEvent;
                class TimeEvent;
                // Constructor
                Event(int measure, int beat, int pos);
        };
        // Sample Event Class (inherit to Event Class)
        class Event::SampleEvent : public Event
        {
            public:
            // variable in SampleEvent Class
            int ID;
            float Pan;
            float Vol;
            // Constructor
            SampleEvent(int id, float pan, float vol, int measure, int beat, int pos);
        };
        // Time Event Class (inherit to Event class)
        class Event::TimeEvent : public Event
        {
            public:
            // variable in TimeEvent Class
            double Value;
            // Constructor
            TimeEvent(double value, int measure, int beat, int pos);
        };
        // Constructor of Event
        Event::Event(int measure, int beat, int pos)
        {
            Measure         = measure;
            Beat            = beat;
            Position        = pos;
        }
        // Constructor of Sample Event
        Event::SampleEvent::SampleEvent(int id, float pan, float vol, int measure, int beat, int pos) : Event(measure, beat, pos)
        {
            ID                      = id;
            Pan                     = pan;
            Vol                     = vol;
            Measure         = measure;
            Beat            = beat;
            Position        = pos;
        }
        // Constructor of Time Event
        Event::TimeEvent::TimeEvent(double value, int measure, int beat, int pos) : Event(measure, beat, pos)
        {
            Value                   = value;
            Measure         = measure;
            Beat            = beat;
            Position        = pos;
        }
    }      
}
#endif

假设,我有2个变量,SETE, SE为SampleEvent和TE为TimeEvent,我只是想将它们插入向量,并从向量中获取它们,这是我当前的代码:

Event::SampleEvent SE = Event::SampleEvent(1000, 0, 0, 10, 10, 10);
Event::TimeEvent TE = Event::TimeEvent(200, 20, 20, 20);
vector<Event> DataEvent;
// insert Event
DataEvent.push_back(SE);
DataEvent.push_back(TE);
// Now I just want to get it back
Event::SampleEvent RSE = DataEvent[0]; // -> Error no suitable user-defined conversion from "Engine::Data::Event" to "Engine::Data::Event::SampleEvent" exists
Event::TimeEvent RTE = DataEvent[0];   // -> Error no suitable user-defined conversion from "Engine::Data::Event" to "Engine::Data::Event::TimeEvent" exists
// And I don't know how to detecting the inheritance Class
// something like if (RSE == Event::SampleEvent) or if (RTE == Event::TimeEvent) @_@

我认为你需要强制转换它来恢复它。因为虽然你可以隐式地将SampleEvent和TimeEvent转换为Event,但你不能隐式地反过来做。

你需要使用一个Event的引用或者一个指向Event的指针来让它在强制转换中正常工作。

使用引用

*removed* you cannot make a vector reference.
使用指针

Event::SampleEvent SE = Event::SampleEvent(1000, 0, 0, 10, 10, 10);
Event::TimeEvent TE = Event::TimeEvent(200, 20, 20, 20);
std::vector<Event*> DataEvent;
// insert Event
DataEvent.push_back(&SE);
DataEvent.push_back(&TE);
// get the events back, note this can throw an exception if you cast incorrectly.
Event::SampleEvent* RSE = (Event::SampleEvent*)DataEvent[0]; 
Event::TimeEvent* RTE = (Event::TimeEvent*)DataEvent[1]; 
/// This also Works using static_cast
//Event::SampleEvent* RSE = static_cast<Event::SampleEvent*>(DataEvent[0]); 
//Event::TimeEvent* RTE = static_cast<Event::TimeEvent*>(DataEvent[1]);  
std::cout << RSE->ID << std::endl;
std::cout << RTE->Value << std::endl;

输出为:1000 200

不可能将子类对象本身强制转换为基类对象,但是对子类对象的引用(如指针)可以很容易地强制转换为基类的引用。

你有一个向量

vector<Event> DataEvent;

所以你应该这样使用:

Event E = DataEvent[0];

如果您键入Event::SampleEvent RSE = DataEvent[0];,那么您没有使用指向基类指针的子类的能力,而只是转换对象。如果你想要这个转换成功,你必须提供转换操作符,或者考虑使用指针向量:vector<Event* > DataEvent;然后,如果你想要获得特定的事件,你可以使用dynamic_cast<>,这将允许你动态地获得子类的对象,只有当它实际上是这个子类对象:记住,你可以有许多不同的子类在你的向量下的公共基类你还需要一些虚拟方法,否则类型不被认为是多态的,你不能使用dynamic_cast<>。添加

就足够了
virtual void f(){}

到Event类