CXO2
CXO2

Reputation: 648

Detecting and Converting inheritance class to base class

I have 3 classes, the one is base class and the others are the inherited classes from the base class, here are the codes of the classes:

// 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

Let say, I have 2 variable, SE and TE, SE for SampleEvent and TE for TimeEvent, I just want to insert them to vector, and get them from the vector, here is my current code:

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) @_@

Upvotes: 1

Views: 1837

Answers (3)

4pie0
4pie0

Reputation: 29724

you have a vector

vector<Event> DataEvent;

so you shoud use it this way:

Event E = DataEvent[0];

if you type Event::SampleEvent RSE = DataEvent[0]; then you are not using the ability to point to a subclass with base class pointer, but simply casting object. if you want this cast to succed you have to provide conversion operator, or think about using vector of pointers instead: vector<Event* > DataEvent; then if you want get specific event you may use dynamic_cast<> which will allow you to dynamically get object of subclass only if it is actually this subclass object: remember you can have many different subclasses in your vector under common base class also you need some virtual methods, otherwise types are not considered as polymorphic and you cannot use dynamic_cast<>. it is enough to add

virtual void f(){}

to Event class

Upvotes: 0

Kyle C
Kyle C

Reputation: 1637

I believe you need to cast it to get it back. Because while you can implicitly cast a SampleEvent and TimeEvent to an Event, you cannot do it the other way around implicitly.

You will need to either use a reference of Event or a pointer to Event to get this to work properly with casting.

Using References

*removed* you cannot make a vector reference.

Using Pointers

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;

The output is: 1000 200

For more about casting see this stackoverflow answer.

Upvotes: 1

stevedes
stevedes

Reputation: 46

It's not possible to cast an subclass object itsef to a base class object, but rather a reference (like a pointer) to a subclass object can be easily casted to a reference of a base class.

Upvotes: 0

Related Questions