I'm trying to rewrite the following C# functionality in C++, but there's now a lot more I need to think about:
public abstract class Component
{
}
public class Entity
{
private List<Component> m_components = new List<Component>();
public T AddComponent<T>() where T : Component
{
if (typeof(T).IsSubclassOf(typeof(Component)))
{
T newComponent = Activator.CreateInstance<T>();
m_components.Add(newComponent);
return newComponent;
}
else
{
return null;
}
}
public Component AddComponent(Type t)
{
if (t.IsSubclassOf(typeof(Component)))
{
Component newComponent = (Component)Activator.CreateInstance(t);
m_components.Add(newComponent);
return newComponent;
}
else
{
return null;
}
}
}
This is as far as I got:
class Component
{
Component() { }
~Component() { }
void OnCreate() = 0;
}
class Entity
{
public:
template<class N> void Entity::AddComponent()
{
N *newComponent = new N();
m_components->push_back(newComponent);
newComponent->OnCreate();
}
private:
std::vector<Component*> *m_components;
}
Googling and reading up on templates did some good but at this point I think I need an experienced programmers view on this. Am I on the right tracks? I'm getting 'unresolved external symbol' errors and the C++ code isn't validating that it's creating a subclass of the correct type. I appreciate this might encompass a couple of topics but it would be great if anyone could give me a hand!
I think the right path is to experiment with smart pointers. Here's some sfinae based approach doing somewhat the same thing as you did in your C# solution:
#include <memory>
#include <vector>
#include <type_traits>
class Component {
public:
Component() { }
~Component() { }
virtual void OnCreate() = 0;
};
class Entity {
public:
template<class T> std::enable_if_t<std::is_base_of<Component, T>::value> AddComponent() {
auto inserted = std::make_shared<T>();
inserted->OnCreate();
m_components.push_back(std::move(inserted));
}
template<class T> std::enable_if_t<!std::is_base_of<Component, T>::value> AddComponent() {
}
private:
std::vector<std::shared_ptr<Component>> m_components;
};
class Component1: public Component {
public:
void OnCreate() { }
};
class Component2: public Component {
public:
void OnCreate() { }
};
class Component3 {
public:
void OnCreate() { }
};
int main() {
Entity e;
e.AddComponent<Component1>();
e.AddComponent<Component2>();
e.AddComponent<Component3>(); // won't add anything to your entity
// as Component3 is not a subclass of
// Component
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.