Dynamic Cast Template, anything is everything.

I store a vector of base class pointers, I'm trying to dynamic cast it to a derived class pointer, there are several derived classes, none of the classes have any virtual methods.

The problem is that it dynamic casts based on a template argument, so regardless of what derived class it may have been when I added it to the vector of base class pointers, it can now be converted into any of the derived classes, losing all of its data which is obviously besides the point.

when adding a component it checks if the component has already been added, but there is no way to know because the base class pointer can be turned into any of its derived classes, so there will always only be 1 component, and even if I forcibly add components to the vector it will always return me the first component for the same reason.

does anyone have a solution for this? I'm trying to implement a component entity system.

Component.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef COMPONENT_HPP
#define COMPONENT_HPP

//STD
#include <string>
//3RD

//SELF

//this is just a shell to allow me to store generic components in vectors

class Component
{
public:
    Component();
    virtual ~Component();
    Component& operator=(const Component&);
    const std::string name = "Component";
};

#endif 


Entity.hpp / get component function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef ENTITY_HPP
#define ENTITY_HPP

//STD
#include <vector>
#include <iostream>
#include <typeinfo>

//3RD

//SELF
#include "Component.hpp"
#include "HealthComponent.hpp"
#include "VelocityComponent.hpp"

class Entity
{
public:
    Entity();
    ~Entity();
    unsigned int id = 0;
    template <class T> T* addComponent();
    template <class T> bool removeComponent();
    template <class T> bool hasComponent();
    template <class T> T* component();
private:
    std::vector<Component*> m_Components;
};

template <class T>
T* Entity::component()
{
    if (!this->hasComponent<T>())
    {
        return nullptr;
    }

    T* comp = new T();

    for (unsigned int i = 0; i < m_Components.size(); ++i)
    {
        if (typeid(dynamic_cast<T*>(m_Components.at(i))).name() == typeid(comp).name())
        {
            std::cout << "---\n" << typeid(dynamic_cast<T*>(m_Components.at(i))).name() << "==" << typeid(comp).name() << "\n";
            delete comp;
            comp = nullptr;
            std::cout << typeid(T*).name() << "\n";
            std::cout << "i = " << i << " / size = " << m_Components.size() <<"\n---\n";
            return dynamic_cast<T*>(m_Components.at(i));
        }
        else
        {
            std::cout << "---\n" << typeid(dynamic_cast<T*>(m_Components.at(i))).name() << "!=" << typeid(comp).name() << "\n---\n";
        }
    }

    delete comp;
    comp = nullptr;

    std::cout << "ret nullptr\n";

    return nullptr;
}
Last edited on
closed account (o1vk4iN6)
Well it looks like you are misusing dynamic_cast. If dynamic_cast succeeds then you know it is of the type T, so I don't really get why you are comparing the typeid after that. Not to mention it is a relatively costly operation you should only do it once and store the result instead of copy and pasting it everywhere. Also not sure about "hasComponent()" but it seems like it would do almost exactly the same thing as component() (iterate through the vector trying to dynamically cast to the type).

Can there only be one type of each specific component ?
you're right, I could just check if its nullptr or not.

right now I don't see a need to have more than one specific type of component, so yes.

I realize my implementation is pretty sucky right now, it's the result of some hacking and being revived from my recycling bin, but the main problem is how do I identify what the original derived class was when its stored in a vector of pointers to the base class.

after it is actually working I can then focus on optimizing it.
Last edited on
Topic archived. No new replies allowed.