Converting Derived Type to Base Type

I am trying to learn type casting from base class to derived class. This sample will show you what I am trying to do. I know this is not a valid solution. I am just trying to create a dynamic architecture for my software and open for advices, solutions.

enum EComponentType
{
    Base = 0,
    Material = 1
};

class FComponent
{
public:
    FComponent() { m_type = EComponentType::Base; }

    EComponentType type() { return m_type; }

protected:
    EComponentType m_type;

};

class FMaterial : public FComponent
{
public:
    FMaterial() { m_type = EComponentType::Material; }

    void setValue(int value) { m_value = value; }
    int value() { return m_value; }

private:
    int m_value;

};

int main(int argc, char *argv[])
{
    FMaterial material;
    material.setValue(22);

    QVector<FComponent> Components;
    Components << material;

    for (int i = 0; i < Components.size(); i++)
    {
        switch (Components[i].type())
        {
        case EComponentType::Material:

            FMaterial material = (FMaterial)(Components[i]); // --> invalid of course

            int value = material.value();
            break;
        }
    }

    return 0;
}

Update 1:

int main(int argc, char *argv[])
{
    QVector<FComponent*> Components;

    FMaterial material;
    material.setValue(22);


    Components << &material;

    for (int i = 0; i < Components.size(); i++)
    {
        switch (Components[i]->type())
        {
        case EComponentType::Material:

            FMaterial *m = static_cast<FMaterial*>(Components[i]);

            int value = m->getValue();
            qDebug() << value;
            break;
        }
    }

    return 0;
}

So is this a good choice due to performance or any other reasons? There will be lots of classes and many types?

Upvotes: 0

Views: 185

Answers (1)

pasztorpisti
pasztorpisti

Reputation: 3726

Although I do not agree with your overall design here is how to fix your solution:

Use static_cast instead of dynamic_cast and it will work. dynamic_cast will also work if you put at least one virtual function to the base class but its an overkill and would be redundant along with your type enum.

EDIT: Also I've just noticed that you try to cast values, in case of classes you have to do the casting on class pointers or references!

class FComponent
{
public:
    // Withtout this if you delete an FComponent* then the destructor of the derived class isn't called.
    virtual ~FComponent() {}
};

class FMaterial : public FComponent
{

};

int test()
{
    QVector<FComponent*> Components;
    FMaterial* material = new FMaterial;
    Components << material;

    for (int i = 0; i < Components.size(); i++)
    {
        switch (Components[i].type())
        {
        case EComponentType::Material:
            FMaterial* material = static_cast<FMaterial*>(Components[i]);
            int value = material->value();
            break;
        }
    }

    // Somewhere later in your code....            
    for (int i = 0; i < Components.size(); i++)
        delete Components[i];
    // TODO: remove all deleted pointers from Components

    return 0;
}

Upvotes: 2

Related Questions